【问题标题】:Q promises chaining to do things in correct orderQ 承诺链接以正确的顺序做事
【发布时间】:2016-04-22 23:18:27
【问题描述】:

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

我的函数如下所示:

  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 中记录的承诺来实现它,但它运行不正常。不知何故,我没有来到“然后”块。

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

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

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;
    });
}

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

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;
 }

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

 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;
                      });
                    });
                  });
                });
              });
            });
          });
        });
      });
    });

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

【问题讨论】:

标签: javascript node.js promise q


【解决方案1】:

异步调用没有“正确顺序”的概念,因为它们就是异步调用,它们可以在任何时候结束。

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


在您的情况下,您可能可以递归地执行此操作:

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!
});

【讨论】:

    【解决方案2】:

    尝试从 Promise 中捕获异常。

    return Q.all(promises).then(function (res) {
      return sku;
    })
    .catch(function (error) {
        // Handle any error from all above steps
    });
    

    【讨论】:

    • 我不确定这如何回答这个问题。
    • 发现错误应该会给您/我们更多关于错误的信息以及为什么永远不会履行承诺。
    • @YordanIvanov:但是OP的代码没有错误?肯定有错误,但没有什么会引发拒绝承诺的异常。
    猜你喜欢
    • 2015-02-04
    • 2014-10-31
    • 2015-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多