我在Express/Sequelize应用程序中做了很多基于承诺的操作。为了控制数据流,我想尽可能严格地遵循承诺模型。
以下是我目前正在做的事情的片段:
AreaList.forEach( area => {
distances.push({
target: tgt,
source: area,
distance: areaController.calcDist(tgt, area),
country: areaController.determineCountry(area)
}).then(() => { //this is where I would like to have the .then() function, but get the error.
distances.sort((a1, a2) =>{
return a1.distance - a2.distance;
}).filter(area => area.country === country)
.forEach(area => {
Insider.findAll({
where: {
areaCode: area.source,
country: area.country,
language: language,
gender: gender
}
}).then( insider => {
returnUsers.push(insiders);
}).then(_ => {
returnUsers = returnUsers.splice(0,10);
res.status(200).send(returnUsers);
});
});
});
});
如何为数组提供.then()
,或模拟.then()
?
您遇到的问题是将同步代码与异步代码混合在一起。在上面的代码片段中,您有各种同步代码片段。 AreaList.forEach
、distances.push
、distances.sort
都是同步操作。
在我看来,您要做的是在将代码推送到数组中时处理一些代码,这可能是也可能不是异步的(areaController.calcDist(tgt, area)
(。
假设areaController.calcDist(tgt, area)
是同步操作,我会重写这样的东西:
let distances = AreaList.map(area => {
return {
target: tgt,
source: area,
distance: areaController.calcDist(tgt, area),
country: areaController.determineCountry(area)
};
})
.sort((a1, a2) =>{
return a1.distance - a2.distance;
})
.filter(area => area.country === country);
let findUsers = distances.map(area => {
return Insider.findAll({
where: {
areaCode: area.source,
country: area.country,
language: language,
gender: gender
}
});
});
Promise.all(findUsers).then(users => {
let returnUsers = users.splice(0, 10);
res.status(200).send(returnUsers);
})
.catch(err => {
//handle errors
});
then(( 是 JavaScript promise resolve 提供的函数。 如果你想在浏览区域列表中的每个项目时做一系列的事情,你应该这样做:
pushDistances(distance) {
return new Promise((resolve) => {
distance.push(distance);
resolve();
});
使用 resolve(( 函数,您可以不带任何东西就 resolve((,也可以附加您想要解析的内容:例如您刚刚推送的距离或带有新推送距离的更新距离数组。
resolve(distances) or resolve(distance);
然后在你的 .then(( 中,根据你解析的内容,你可以得到距离或距离。 像这样:
pushDistances().then((distance or distances) => {
within this function you have access to distance or distances: based on what you resolved with.
});
然后你可以链接一堆返回承诺的函数
pushDistances().then(() => anotherFunctionThatReturnsPromise()).then(() => {})
这是对承诺如何运作的一般概述。你应该更多地研究Javascript 承诺,看看你如何链接承诺。