我一直在与 Promise 作斗争,并且想知道 Promise 是如何工作的。 在我的项目中,我使用 Bookshelfjs ORM 从 Postgres 获取数据。
这是我现在正在处理的代码。我在此请求中获得了一组设备 ID,并且每个设备都以两种模式之一运行。
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()
方法执行此操作,但没有成功。是否可以从每个 Promise 中返回
modelOne
或modelTwo
,然后推送到数组?我怎样才能实现这个目标?
最佳答案
尽量避免嵌套then
,并保持 promise 链平坦。此外,您可以将两个模型案例合并为一段代码(DRY)。最后,使用 map
而不是 forEach
,这样您就可以返回一个 Promise 数组,然后您可以将其提供给 Promise.all
:
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);
});
}
关于javascript - 如何从 Promise 返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45122086/