2013-10-11 66 views
0

我正在開發一些anync的東西,我真的很想以一種很好的方式實現它。從延期的回調中退回承諾

考慮下面的代碼

function getData(latency) { 
    var deferred = $.Deferred(); 

    window.setTimeout(function() { 
     deferred.resolve(Math.random()); 
    }, latency + 100); 

    return deferred.promise(); 
} 
function getSpecialData() { 
    var deferreds = []; 
    for (var i = 0; i < 3; i++) { 
     deferreds.push(getData(1000 * i)); 
    } 
    return $.when.apply($, deferreds); 
} 

function log(msg) { 
    $("#console").append("<li>" + msg + "</li>"); 
    console.log(msg); 
} 

getData(3000) 
.done(function() { 
    log("got 3000 data"); 
    return getSpecialData() 
    .done(function() { 
     log("got special data"); 
    }); 
}) 
.always(function() { 
    log("got all data"); 
}); 

正如你所看到的,我回來來自的getData和getSpecialData函數中的承諾。我也按照你看到的方式將這些功能鏈接在一起。更重要的是,我在getData done回調中返回了一個承諾。

我一直期待延期對象關心它的回調是什麼樣的回報,如果它是一個承諾,等待這個承諾解決,然後再回調。實際發生的是它不關心我在回調中返回的內容。順序是:

  1. 呼叫的getData,後3秒得到"got 3000 data"信息,
  2. 同時火getSpecialData和always回調與"got all data"消息

我想實現的是以下函數調用順序:

  1. 調用getData,3s後得到"got 3000 data"信息,
  2. 調用getSpecialData,3s後獲得"got special data"信息,
  3. 緊接在"got all data"後面的消息。

使其按照我想要的方式工作的最佳方法是什麼?

回答

1

這正是.then()(或jQuery 1.8之前的.pipe())所做的。

打電話,而不是.done()

+0

嗯,你是對的。我一定誤解了這兩者之間的區別。用'.then()'看起來效果很好。但是,似乎還有必要回報這個內在的承諾,所以我願意。謝謝 – patryk

0

您不能撥打return任何東西,因爲這沒什麼意義 - 結果不會在調用者的任何地方使用,它的類型實際上是void

要鏈接操作,您可以使用then而不是done。該方法將返回回調的(異步)結果的承諾,這本身可能是一個承諾。