Javascript 如何从承诺中回报价值
我一直在与承诺作斗争,我想知道承诺是如何运作的。 在我的项目中,我使用BookshelfFJS ORM从Postgres获取数据 这是我现在正在编写的代码。我在这个请求中得到一个设备ID数组,每个设备都以两种模式之一运行Javascript 如何从承诺中回报价值,javascript,postgresql,express,promise,bookshelf.js,Javascript,Postgresql,Express,Promise,Bookshelf.js,我一直在与承诺作斗争,我想知道承诺是如何运作的。 在我的项目中,我使用BookshelfFJS ORM从Postgres获取数据 这是我现在正在编写的代码。我在这个请求中得到一个设备ID数组,每个设备都以两种模式之一运行 router.post('/devices', function (req, res, next) { var currentData = []; var deviceIds = req.body.devices; loadash.forEach(deviceIds, func
router.post('/devices', function (req, res, next) {
var currentData = [];
var deviceIds = req.body.devices;
loadash.forEach(deviceIds, function (device) {
var deviceid = device.deviceid;
Device.forge()
.where({deviceid: deviceid})
.fetch({columns: ['id', 'mode']})
.then(function (fetchedDevice) {
if(fetchedDevice.get('mode') === 1) {
Model_1.forge()
.where({device_id: fetchedDevice.get('id')})
.orderBy('epoch_time', 'DESC')
.fetch()
.then(function (modelOne) {
//first push
currentData.push(modelOne.toJSON());
//array with first push data
console.log(currentData)
})
.catch(function (err) {
console.log(err);
});
}
else if(fetchedDevice.get('mode') === 2) {
Model_2.forge()
.where({device_id: fetchedDevice.get('id')})
.orderBy('epoch_time', 'DESC')
.fetch()
.then(function (modelTwo) {
//second push
currentData.push(modelTwo.toJSON());
//array not empty here(shows data from both push)
console.log(currentData);
})
.catch(function (err) {
console.log(err);
});
}
})
.catch(function (err) {
console.log(err);
});
});
//This shows an empty array
console.log('Final: ' +currentData);
});
现在,我知道这是因为Javascript的异步特性。我的问题是
push()
之后,如何显示最终数组?我尝试使用Promise.all()
方法来实现这一点,但没有成功modelOne
或modelTwo
,然后推送到一个数组?我怎样才能做到这一点.map()
和Promise.all()
,返回从函数传递到的值。然后()
尽量避免嵌套,然后
,并保持承诺链平坦。此外,您可以将两个模型案例连接到一段代码中(DRY)。最后,使用map
而不是forEach
,这样您可以返回一个承诺数组,然后将其馈送到Promise。所有:
router.post('/devices', function (req, res, next) {
var promises = loadash.map(req.body.devices, function (device) {
return Device.forge()
.where({deviceid: device.deviceid})
.fetch({columns: ['id', 'mode']})
.then(function (fetchedDevice) {
var model = [Model_1, Model_2][fetchedDevice.get('mode')-1];
if (model) {
return model.forge()
.where({device_id: fetchedDevice.get('id')})
.orderBy('epoch_time', 'DESC')
.fetch();
}
}).catch(function (err) {
console.log(err);
});
});
Promise.all(promises).then(function (currentData) {
currentData = currentData.filter(model => model) // exclude undefined
.map(model => model.toJSON());
console.log('Final: ' +currentData);
});
}
1.您将需要类似Promise.all(arrayOfThings.map(()=>(//返回一个Promise))的内容。然后((results//array of result)=>(u.forEach(…));2.您可以通过解析从promise返回对象。您可以通过解析({modelOne:…,modelTwo:…})返回,然后在then函数中使用它们((result)=>{use it})@正如我所说,我尝试了Promise.all()
,但我只从Device.forge()中获得了价值。也许我做错了,或者把它放错了位置。你能解释一下我如何用Promise.all()正确实现这一点吗?你的代码是这样的:假设你为一个名为deviceFunc()的设备包装了所有异步函数{返回新的Promise((解析,拒绝)=>(if(model1)resolve(model1)else resolve(model1))}。您希望获得所有设备的阵列。您确实承诺了。所有(devices.map((device,index)=>(deciveFunc(device)))应该.catch()
链接到Promise.all()
?它可以在那里,也可以在单个承诺上。在第二种情况下,您仍然会得到基于其他承诺的结果。取决于OP的期望。太棒了!这一切如期而至。所以我想知道我是否正确理解了-returnmodelone.toJSON()
将值返回给outerthen()
,而这个outerthen()
函数将值返回给map
函数,对吗?是的。.toJSON()
是否返回一个承诺
或一个不是承诺
的值?我认为它返回一个带有模型属性值的承诺。从返回的承诺
应该在chained处得到承诺的值。然后()(res=>Promise.resolve(2).then(data=>data)).then(res=>console.log(res))//2
对不起,根据书架文档toJSON()
将序列化模型作为普通对象返回
router.post('/devices', function (req, res, next) {
var promises = loadash.map(req.body.devices, function (device) {
return Device.forge()
.where({deviceid: device.deviceid})
.fetch({columns: ['id', 'mode']})
.then(function (fetchedDevice) {
var model = [Model_1, Model_2][fetchedDevice.get('mode')-1];
if (model) {
return model.forge()
.where({device_id: fetchedDevice.get('id')})
.orderBy('epoch_time', 'DESC')
.fetch();
}
}).catch(function (err) {
console.log(err);
});
});
Promise.all(promises).then(function (currentData) {
currentData = currentData.filter(model => model) // exclude undefined
.map(model => model.toJSON());
console.log('Final: ' +currentData);
});
}