如何构建模块化的js承诺链

How to build modular js promise chains?

本文关键字:js 承诺 模块化 何构建 构建      更新时间:2024-06-04

我有一个promise链,它目前正在运行,具有非常基本的错误处理功能。如果某个步骤失败,则不会运行后续步骤。如果出现故障,我希望以后能够继续承诺链,并且应该从中断的地方开始。

这就是我当前的代码:

// controller.js
var failure = false;
QueryFactory.step1()                      // Step 1
   .then(function(msg){
      if(failure == false){
        console.log("Finished Step 1");
        return QueryFactory.step2();
      }
   }, function(err){
      console.log(err);
      failure = true;
   })
   .then(function(msg){                   // Step 2
      if(failure == false){
         console.log("Finished Step 2");
         return QueryFactory.step3();
      }
   }, function(err){
      console.log(err);
      failure = true;
   })
   .then(function(msg){                   // Step 3
      if(failure == false){
         console.log("Finished Step 3");
      }
   }, function(err){
      console.log(err);
      failure = true;
   })

我的工厂看起来是这样的:

// QueryFactory.js
step1 = function(){
   var deferred = $q.defer();
   $http.post('/task', {step_num: 1})
      .then(function(data)){
         deferred.resolve(data);
      }, function(err){
         deferred.reject(err);
      });
   return deferred.promise;
}
// step2 and step3 are similar

但是,也许有一种更好的编写方式可以实现模块化?假设步骤2失败了,我如何设计一种方法,让用户可以点击一个按钮,稍后继续从步骤2开始的链接?

看看.then(…).catch(…).then(…, …)之间的区别。在您的情况下,通过将第二个回调传递给then,您最终会跳过当前步骤,而不是继续您停止的步骤

QueryFactory.step1()
.then(function(msg) {
    console.log("Finished Step 1 without error");
    return msg;
}, function(err) {
    console.log(err);
    …
}).then(function() {
    return QueryFactory.step2();
}).then(function(msg) {
    console.log("Finished Step 2 without error");
    return msg;
}, function(err) {
    console.log(err);
    …
}).then(function() {
    return QueryFactory.step3();
}).then(function(msg) {
    console.log("Finished Step 3 without error");
    return msg;
}, function(err) {
    console.log(err);
    …
}).then(function(res) {
    console.log("everything is finished");
}).catch(function(err){
    console.error("something bad happened", err);
});

(或者,如果您不需要这些日志,您可以使用普通的.catch而不是then,回调告诉您步骤是否完成而没有错误)

现在,代码中的是什么?这是你的要求

如果出现故障,我希望以后能够继续承诺链

部分中,您需要处理错误,并返回失败步骤的无错误结果承诺,例如重试。这个承诺只会在"稍后时间"实现——您可以等待用户确认错误、超时或任何您想要的。

一旦您从错误回调返回的承诺得到解决,链将继续。