我正在编写一个Node.js脚本,该脚本接受一个对象数组,这些对象代表记录不同测量值的不同设备。我想使用Knex.js将有关设备的信息存储在PSQL数据库中,但只想存储代表新的/唯一设备的对象中的设备信息。只要同一设备出现在不同的POST请求中,插入之前对device_id的验证似乎可以正常进行。但是当同一台设备出现时 在同一个POST请求中,程序的异步特性似乎导致验证在插入完成之前进行。
我试图使脚本调用两个单独的异步等待函数(一个用于验证,另一个用于实际插入),但是不确定这是否是最简单的方法,还是我做得对,因为无论如何它都会失败。
app.post('/testsite', (req, res) => {
const data = (req.body.measurements);
for (let i = 0; i < data.length; i++) {
database.select("device_id").from("device_info").where("device_id", data[i].device_id)
.then(MatchList => {
console.log(MatchList);
if (MatchList.length === 0) {
return database('device_info')
.returning('device_id')
.insert({
device_id: data[i].device_id,
device_name: data[i].device_name,
site_id: data[i].site_id,
site_name: data[i].site_name
})
.then((newdevice) => {
console.log('inserted device id', newdevice);
});
}
return;
});
}
});
我希望验证失败时它不会插入,但是似乎验证永远不会失败,即使应该验证也不会出现此错误:
Unhandled rejection error: duplicate key value violates unique constraint "device_info_pkey"
答案 0 :(得分:0)
我不确定该问题是否是由于knex的异步特性引起的,还是该问题是其他原因引起的。但是,我重新编写了您的代码,以使用async / await语法使其更具可读性。自从我添加了.first()
以来,我还只是在检查设备是否返回null而不是数组。调用此函数时,您能否检查device
是否获得控制台记录?
app.post('/testsite', async (req, res) => {
const data = (req.body.measurements);
for (let i = 0; i < data.length; i++) {
const device = await database
.select('*')
.from('device_info')
.where('device_id', data[i].device_id)
.first();
console.log(device);
if (device) {
const newDevice = await database
.from('device_info')
.insert({
device_id: data[i].device_id,
device_name: data[i].device_name,
site_id: data[i].site_id,
site_name: data[i].site_name
})
.returning('*');
return newDevice;
} else {
return device;
}
}
});
答案 1 :(得分:0)
我终于能够解决问题。本质上,仅在搜索和插入上使用async等待是不够的,因为for循环仍将移至下一个元素。为了解决这个问题,我向POST请求发出了一个异步函数。
app.post('/testsite', (req,res) =>
{ const data = (req.body.measurements);
postfxn(data); } )
此函数等待for循环的每次迭代。
async function postfxn(data){
for(let i =0; i<data.length; i++){
await insertdevice(data[i]); }
}
然后,插入设备功能使用async等待来搜索该设备,并根据technogeek1996的答案建议将其插入数据库中。
希望这可以帮助其他遇到类似问题的人