Q 承诺链接以正确的顺序做事 [英] Q promises chaining to do things in correct order

查看:49
本文介绍了Q 承诺链接以正确的顺序做事的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个异步函数,需要以正确的顺序多次调用.这是关于将图像上传到服务器,但就像我说的图像应该以正确的顺序上传.

I have a asynchronous function that needs to be called multiple times in the correct order. It's about uploading images to a server but like I said the images should be uploaded in the correct order.

我的函数如下所示:

  function uploadImage(sku,fileName) {
    console.log("Uploading image for sku="+sku+", imageName="+fileName);

    var deferred = Q.defer();

    var readStream = fs.createReadStream(rootPath+'/data/'+sku+"/"+fileName);
    var req = request.post('http://localhost:3000/'+sku+'/upload/'+fileName);

    readStream.pipe(req);

    req.on('end', function() {
      console.log("Image imageName="+fileName+" uploaded successfully.");
      db.updateLastUploadedImage(sku,fileName).then(function (res) {
        if(res) {
          console.log("Table watches for sku="+sku+" updated.");
          deferred.resolve(sku);
        }
      });
    });

    req.on('error',function(err) {
      deferred.reject(err);
    });

    return deferred.promise;
  }

我试图通过链接 https://github.com/kriskowal/q 中记录的承诺来实现它 但效果不佳.不知何故,我没有进入然后"块.

I tried to bring it on with chaining the promises like documented in https://github.com/kriskowal/q but it's not working well. Somehow I do not come to the "then" block.

所以我尝试创建一个递归函数,但它也没有进入函数调用的then"块.

So I tried to make a recursive function but it also does not go inside the "then" block of the function call.

只有这种方法有效,但它没有按照正确的顺序运行.

Only this method works but its not running through the correct order.

function uploadImages(sku) {
    var promises = [];

    for(var x=0; x<10; x++) {
      promises.push(uploadImage(sku,(x+1)+".jpg")));
    }

    return Q.all(promises).then(function (res) {
      return sku;
    });
}

我的递归解决方案如下所示:

My recursive solution looks like this:

function uploadImages(sku,current,max) {
    var deferred = Q.defer();

    if(current<=max) {
      uploadImage(sku,current+'.jpg').then(function (res) {
        if(res) {
          uploadImages(sku,current+1,max);
        }
      }, function (err) {
        deferred.reject();
      });
    } else {
      deferred.resolve(sku);
    }

    return deferred.promise;
 }

我正在寻找的是这样的东西(但这不是实现的方式):

What I'm looking for is something like this (but thats not the way to implement):

 return uploadImage(sku,"1.jpg").then(function(res) {
      return uploadImage(sku,"2.jpg").then(function(res) {
        return uploadImage(sku,"3.jpg").then(function(res) {
          return uploadImage(sku,"4.jpg").then(function(res) {
            return uploadImage(sku,"5.jpg").then(function(res) {
              return uploadImage(sku,"6.jpg").then(function(res) {
                return uploadImage(sku,"7.jpg").then(function(res) {
                  return uploadImage(sku,"8.jpg").then(function(res) {
                    return uploadImage(sku,"9.jpg").then(function(res) {
                      return uploadImage(sku,"10.jpg").then(function(res) {
                        return sku;
                      });
                    });
                  });
                });
              });
            });
          });
        });
      });
    });

那么,对于我而言,最佳实践是什么?

So what is the best practice for my purpose?

推荐答案

异步调用没有正确顺序"的概念,因为它们就是这样——异步并且可以随时结束.

There is no concept of "correct order" for async calls because they are just that -- asynchronous and they can end at any point.

Q.all(promises).then(...) 中的回调中,您应该按照做出响应的顺序获得响应,但控制台记录的顺序可能不由于它们的异步性质而处于相同的顺序.

In your the callback in Q.all(promises).then(...) you should have the responses in the order that you made them, but the order of your console logs may not be in the same order due their asynchronous nature.

在您的情况下,您可能可以递归执行:

In your case, you can probably do it recursively:

function uploadFiles(sku, current, max) {
     return uploadImage(sku, current + '.jpg').then(function (sku) {
          if (current > max) { return sku; }

          return uploadFiles(sku, current + 1, max);
     });
}

// use it
uploadFiles('SOME_SKU', 1, 10).then(function (sku) {
    // ALL DONE!
});

这篇关于Q 承诺链接以正确的顺序做事的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆