2017-05-03 118 views
-1

我想了解Promises如何使用jQuery。 这是我的沙箱:jQuery推迟/ Promises

function test1() { 
     var deferred = $.Deferred() 
     setTimeout(function() { 
      deferred.resolve(1); 
      //deferred.reject(2); 
     }, 2000); 
     return deferred.promise(); 
    } 

    function test2() { 
     var deferred = $.Deferred() 
     setTimeout(function() { 
      deferred.resolve(2); 
      // deferred.reject(2); 
     }, 1000); 
     return deferred.promise(); 
    } 

    function doTest(){ 
     $.when(test1()).then(
      function (a) { 
       console.log('test1 finished', a) 
       return test2(); 
      }, 
      function (a) { 
       console.log('something failed in test1', a) 
      } 
     ).then(
      function (b) { 
       console.log("test2 finished", b); 
      }, 
      function (b) { 
       console.log("something failed in test1", b); 
      } 
     ); 
    }  

它的工作原理如我所料 - 书面方式:

test1的完成1

test2的完成2

但是,当我改变它像下面:

 function test1() { 
     var deferred = $.Deferred() 
     setTimeout(function() { 
      // deferred.resolve(1); 
      deferred.reject(2); 
     }, 2000); 
     return deferred.promise(); 
    } 

    function test2() { 
     var deferred = $.Deferred() 
     setTimeout(function() { 
      deferred.resolve(2); 
      // deferred.reject(2); 
     }, 1000); 
     return deferred.promise(); 
    } 

其写入到控制台:在测试1 2

test2的成品不确定

的是不是事实

东西失败了,因为test2的尚未执行,甚至。

我想,“test2完成未定义”不应该显示。

我猜在第二时间有什么不对,但是什么?

+0

您或者需要在错误处理程序中调用'test2',或者您需要仅在test2()'promise上安装“test 2 finished”记录结果处理程序,否则您将不需要在它之前赶上错误。 – Bergi

+0

听起来像你学习jQuery 1.x/2.x中的Deferreds/Promises,你现在使用3.x,它的行为不同(也就是正确)。在3.x中,缺省捕获处理程序('.then()'的第二个参数) - 承诺链沿着其成功路径继续向下,除非抛出/重新抛出错误,或者返回的承诺(最终)被拒绝。 –

回答

0

你的问题实际上是在第一个then的onRejected函数中。具体而言,因为您“返回一个值”(未定义),那么链中的下一个then处理程序将其视为满足承诺的

$.when(test1()).then(
     function (a) { 
      console.log('test1 finished', a) 
      return test2(); 
     }, 
     function (a) { 
      console.log('something failed in test1', a) 
      // Your problem is here. 
     } 
    ).then(
     function (b) { 
      console.log("test2 finished", b); 
     }, 
     function (b) { 
      console.log("something failed in test1", b); 
     } 
    ); 

这可以在某些情况下是有用的:

$.when(riskyFunction()).then(
    function (value) { 
    return processValue(value); 
    }, function (error) { 
    console.log(error); 
    return defaultValue;   // This lets you recover... 
    }).then(function (value2) { 
    return processValue2(value2); // so this handler runs regardless of 
            // riskyFunction's return value. 
    }); 

通过比较来同步代码,这是一个狭窄的try块匹配:

try { 
    a = test1(); 
    b = test2(); 
} catch (e) { 
    console.log('something failed in test1', a) 
} 
console.log("test2 finished", b); // this runs even if test1 or test2 fails, 
            // but in those cases b is undefined! 

相反,你应该删除你的错误处理程序并在最后捕获错误,或至少return $.reject(a)throw a继续跟踪您的中的错误链处理程序。