首页 > node.js中 循环中嵌套了异步,怎么让它实现类似同步的效果。。

node.js中 循环中嵌套了异步,怎么让它实现类似同步的效果。。

displayService.getByMerchantId(req.query.merchantId).then((displays)=> {
      displays.forEach(function (display) {
        imageService.getByDisplayId(display.id).then((image)=> {
          display.image = image;
        });
      });
      res.send(displays);
    }).catch((error)=> {
      res.send(JSON.stringify({
        result: -1,
        reason: '查找失败'
      }));
    });

这样写没得用。。。then 回调函数的动作会在res.send(displays)后面执行。。- - 这样查到的数据是不正确。。。怎样 让then后面执行完了再执行res勒


var co = require('co');  
var store = yield stores.find(...).exec();  
store.forEach(co(function *(obj) {  
    var extra = yield extras.find(...).exec();
}));

这就是我为什么喜欢koa而不喜欢express的原因,yield多好用~一点都不反人类。


我看你都用到了 Promise 了,那就用 Promise 的方法来处理这个问题好了,可以使用 Promise.map() 方法

javascriptdisplayService.getByMerchantId(req.query.merchantId).then((displays)=> {
  return Promise.map(displays, function (display) {
    return imageService.getByDisplayId(display.id).then(function (image) {
      display.image = image;
      return display;
    });
  });
}).then(function (displays) {
  res.send(displays);
}).catch((error)=> {
  res.send(JSON.stringify({
    result: -1,
    reason: '查找失败'
  }));
});

推荐使用 bluebird 这个 Promise

如果你本来用的就是 bluebird,你还可以像下面这样:

jsdisplayService.getByMerchantId(req.query.merchantId).map(function (display) {
  return imageService.getByDisplayId(display.id).then(function (image) {
    display.image = image;
    return display;
  });
}).then(function (displays) {
  res.send(displays);
}).catch((error)=> {
  res.send(JSON.stringify({
    result: -1,
    reason: '查找失败'
  }));
});

1)你为什么不能再getByMerchantId的时候把image也同时获取了呢。你现在这样做多麻烦呀
2)如果一定要这样做,那么参考以下代码

(function(watchLength){
     var current=0;
     displays.forEach(function (display) {
        imageService.getByDisplayId(display.id).then((image)=> {
          display.image = image;
          current++;
          if(current===watchLength){
             res.send(displays);
          }
        });
      });
}(displays.length));

如果你用的mySQL,直接关联查询
如果用的mongodb,在Merchant的model添加一个属性image,就像这样

var Merchant= new Schema({
    image: {
        type: Schema.Types.ObjectId,
        ref: 'Image'
    }   
});

var Image= new Schema({
    name: String   
});

MerchantDao.find(params)          
            .populate('image')           
            .exec();

查询的时候,会直接查出Image的内容,不需要先查出所有的Merchant,在遍历去查询Image

【热门文章】
【热门文章】