nodejs中的异步和并行函数

时间:2014-10-02 10:25:59

标签: node.js asynchronous node-async

我在异步模块中使用parallel()函数得到并发出...

数组images为空......

var asyncTasks = [];

switch(type){
  case 'instafilm':

    var newFileName;
    var images = [];

    selectedPhotos.forEach(function(id){
      newFileName = pathDir + '/' + id + '.jpg';
      asyncTasks.push(function(callback){
        self.api.media(id, function(err, media, remaining, limit) {
          images.push(media.images.thumbnail.url);
        });
      });
    });

    asyncTasks.push( function(callback){
      console.log(images); // empty
    });


    break;
}

console.log(images); // empty

编辑#1:

var asyncTasks = [];

var newFileName;
var images = [];

selectedPhotos.forEach(function(id){
  newFileName = pathDir + '/' + id + '.jpg';
  asyncTasks.push(function(callback){
    self.api.media(id, function(err, media, remaining, limit) {
      images.push(media.images.thumbnail.url);
      callback(null);
    });
  });
});

asyncTasks.push( function(callback){
  console.log(images); // before creating .zip I need to write files using images[]
  gm()
  .in('-page', '+0+0')
  .in('./public/images/instafilm.jpg')
  .in('-page', '+10+10')
  .in(images[0])
  .in('-page', '+10+30')
  .in(images[1])
  .in('-page', '+10+60')
  .in(images[2])
  .in('-page', '+10+90')
  .in(images[3])
  .mosaic()
  .minify()
  .write(newFileName, function (err) {
    if (!err) console.log('done');
    if (err) console.log(err);
    callback();
  });
});



async.parallel(asyncTasks, function(){
    // here I write a .zip file
    var admZip = new AdmZip();
    var pathDir = './public/uploads/'+reference;
    admZip.addLocalFolder(pathDir);
    var willSendthis = admZip.toBuffer();
    admZip.writeZip('./public/uploads/'+reference+'.zip');   
});

1 个答案:

答案 0 :(得分:1)

如果我理解您的代码段,则永远不会调用callback函数:

self.api.media(id, function(err, media, remaining, limit) {
  images.push(media.images.thumbnail.url);
});

这是一个问题。

我能想到的另一个问题是你在执行这个片段之后调用console.log(images)(因为尚未执行异步代码)并且作为并行调用的一部分。但它的名字暗示着平行(并且doc确认)运行你的任务" parallel" (尽管节点允许)。

因此,特别是因为console.log()是同步的,所以您的媒体([...])呼叫在控制台呼叫之前没有时间完成。

如果我猜对了,那么你需要添加一个这样的回调:

function(callback){
  self.api.media(id, function(err, media, remaining, limit) {
    images.push(media.images.thumbnail.url);
    callback(null);
  });
}

在之后检查图像内容,您的异步代码完成如下:

parallel(asyncTasks,function(){
  console.log(images)
})

修改: 根据新的代码片段:

代码的第一部分看起来没问题,直到gm调用wich应该这样做:

async.parallel(asyncTasks, function(){
  gm()
  .in('-page', '+0+0')
  .in('./public/images/instafilm.jpg')
  .in('-page', '+10+10')
  .in(images[0])
  .in('-page', '+10+30')
  .in(images[1])
  .in('-page', '+10+60')
  .in(images[2])
  .in('-page', '+10+90')
  .in(images[3])
  .mosaic()
  .minify()
  .write(newFileName, function (err) {
    if (!err) console.log('done');
    if (err) console.log(err);
    // here I write a .zip file
    var admZip = new AdmZip();
    var pathDir = './public/uploads/'+reference;
    admZip.addLocalFolder(pathDir);
    var willSendthis = admZip.toBuffer();
    admZip.writeZip('./public/uploads/'+reference+'.zip');   
  });
});