2017-05-03 115 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繼續跟蹤您的中的錯誤鏈處理程序。