2012-09-12 103 views
0

我很難用$ .when()同步完成的延遲。 我希望在所有延期完成後得到通知,無論是解決還是失敗。同步延遲與何時

我的問題是當()。always()最初觸發失敗並且不等待其他延遲完成。不知道這是否是一個錯誤。

我做了一個例子,這裏有一個的jsfiddle: http://jsfiddle.net/m3REv/

從它的JS代碼:

/* our multiple deferred we'd like to sync. */ 
var def1 = $.Deferred(); 
var def2 = $.Deferred(); 
var def3 = $.Deferred(); 

def1.done(function() { logger.log('1 done');}).fail(function() {logger.log('1 fail');}); 
def2.done(function() { logger.log('2 done');}).fail(function() {logger.log('2 fail');}); 
def3.done(function() { logger.log('3 done');}).fail(function() {logger.log('3 fail');}); 

$.when(def1, def2, def3).then(function() { 
    logger.log('w then'); 
}).done(function() { 
    logger.log('w done'); 
}).fail(function() { 
    logger.log('w fail'); 
}).always(function() { 
    logger.log('w always'); 
}); 


def1.reject(); 
def2.resolve(); 
def3.resolve(); 

,輸出是:

1 fail 
w fail 
w always 
2 done 
3 done 
+1

這不是一個錯誤。 [The docs](http://api.jquery.com/jQuery.when/)指出,當第一次觀察到的諾言失敗時,when()失效。如果沒有'when()'_is_解析它返回的promise,所以它的'always()'會被觸發。不知道如何解決這個問題,但是你可能需要實現你自己的'when'-like構造。 – lanzz

+0

好吧,那就是缺乏。我終於找到了一張相關的票:http://bugs.jquery.com/ticket/9386但他們不會實現一些東西,直到有人首先想出一個插件。 _sigh_ – BiAiB

回答

0

最後,我寫了一個插件,它是jQuery.when略加修改的版本()。我沒有對它進行徹底的測試,但它現在用於小提琴和我個人的用途。

這裏是一個與插件加上例如撥弄:

http://jsfiddle.net/LTsLJ/

1

解決方法:

var defCount = 3, state = 0; 
var overallAlways = function() { 
    if (++state < defCount) return; 
    logger.log('correct always'); 
}; 

def1.done(function() { logger.log('1 done');}) 
    .fail(function() {logger.log('1 fail');}) 
    .always(overallAlways); 
def2.done(function() { logger.log('2 done');}) 
    .fail(function() {logger.log('2 fail');}) 
    .always(overallAlways); 
def3.done(function() { logger.log('3 done');}) 
    .fail(function() {logger.log('3 fail');}) 
    .always(overallAlways); 

Source

或者somethink像

function overallAlways(defObjects, callback) { 
    var defCount = defObjects.length, state = 0; 
    var alwaysCallback = function() { 
     if (++state < defCount) return; 
     callback.call(this); 
    } 
    $.each(defObjects, function (i, def) { 
     def.always(alwaysCallback); 
    }); 
} 

var defs = [def1, def2, def3]; 
overallAlways(defs, function(){ 
    logger.log("overall always"); 
}); 

Source

+0

好吧,這是一個可行的解決方法,但我希望我不必在每個延遲中都綁定始終回調。 – BiAiB

+0

您不必,可以在'done()'和'fail()'處理程序中調用'overallAlways',但它違反了DRY原則。 – lanzz

+0

感謝您的幫助。無論如何,我已經重寫了$。(請參閱我自己的答案)。現在我可以安然入睡。 – BiAiB