2017-06-15 67 views
2

我有一些函數返回jQuery延遲對象,我無法繞過鏈接並處理結果。返回延遲對象的鏈接函數

請看下面的例子:

const start = Date.now(); 
 

 
// Print a message with a timestamp. 
 
function log (v) { 
 
    console.log(`${Date.now() - start} ${v}`); 
 
} 
 

 
// Return a deferred function that resolves 1 second later with 'value'. 
 
function test (value) { 
 
    log(`test(${value})`); 
 
    return $.Deferred(function (def) { 
 
     window.setTimeout(function() { 
 
      log(`resolve(${value})`); 
 
      def.resolve(value); 
 
     }, 1000); 
 
    }); 
 
} 
 

 
// Example: 
 
test(42) 
 
    .then(function (v) { log(v); }) 
 
    .then(test(99)) 
 
    .then(function (v) { log(v); }) 
 
    .then(function() { log('done'); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

這是應該運行test(42),然後做其結果的東西,然後運行test(99)然後做一些與這些成果,都在訂購。然而,它實際上輸出(第一個數字是毫秒,因爲節目開始):

0 test(42) 
0 test(99) 
1003 resolve(42) 
1003 42 
1003 undefined <-- supposed to be 99 
1005 done 
1005 resolve(99) 

所以test S的兩個被調用,同時在一開始,一切是關閉的。我想輸出是一樣的東西:

0 test(42) 
1000 resolve(42) 
1000 42 
1000 test(99) 
2000 resolve(99) 
2000 99 
2000 done 

我怎樣才能使這項工作?我試過返回$.Deferred(...).promise(),行爲沒有變化,我也嘗試使用done而不是then,但唯一的變化是它第二次打印42而不是undefined

回答

1

每個延遲只能解析一次。對於每個延期鏈,您必須正確附加它們。另外,第二次測試調用需要在函數中,以便它不會立即執行。

const start = Date.now(); 
 

 
// Print a message with a timestamp. 
 
function log (v) { 
 
    console.log(`${Date.now() - start} ${v}`); 
 
} 
 

 
// Return a deferred function that resolves 1 second later with 'value'. 
 
function test (value) { 
 
    log(`test(${value})`); 
 
    return $.Deferred(function (def) { 
 
     window.setTimeout(function() { 
 
      log(`resolve(${value})`); 
 
      def.resolve(value); 
 
     }, 1000); 
 
    }); 
 
} 
 

 
// Example: 
 
test(42) 
 
    .then(function (v) { log(v); }) 
 
    .then(function() { 
 
     test(99) 
 
      .then(function (v) { log(v); }) 
 
      .then(function() { log('done'); }); 
 
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

+0

啊,我知道了,謝謝。像這樣嵌套他們是唯一的方法來做到這一點?所以,如果我說,用for循環構建一個長鏈或者我需要編寫一些輔助函數來順序執行,或者將所有內容都嵌入到這個嵌套表單中? –

+1

一旦推遲解決,它將執行附加到它的所有then(),而不管其中是否包含另一個延遲與否。所以你必須牢記你的邏輯。 – Taplar

+0

順便說一句,我做了一個實驗,玩你的建議,它實際上*出現*正常工作,如果我*只是*使第二次調用測試是一個函數(返回延遲對象),即使沒有嵌套,[像這個](https://pastebin.com/r5Eda5Zp)。也許如果'then'處理程序返回可靠的東西,它會改變鏈中其餘部分的運行? –