如何在数组上使用 .then()?



我在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.forEachdistances.pushdistances.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 承诺,看看你如何链接承诺。

最新更新