2013-09-30 60 views
5

在我的劇本,我需要檢索字典來編碼值轉換爲名稱:有條件承諾

$.ajax({ 
    // retrieve dictionary 
}) 
.done(function(dictionary){ 
    // convert encoded values into names 
}) 
.done(function(){ 
    // run my application 
}); 

但是,有時字典已經被其他應用程序加載,在這種情況下我不需要Ajax調用:

if (dictionary) { 
    // convert encoded values into names 
    // run my application 
} 
else { 
$.ajax({ 
    // retrieve dictionary 
}) 
.done(function(dictionary){ 
    // convert encoded values into names 
}) 
.done(function(){ 
    // run my application 
}); 
} 

這if/else語句是比較重,有沒有辦法把它縮短:

// load dictionary if needed 
// then run my application 

注意:我使用$標記來表示我的僞代碼,但我並不一定與jQuery綁定。

+1

我在我的應用程序中做了很多這類事情。你讓你的想法變得圓滑的是,如果數據是異步獲取的,那麼你必須使用異步方法來訪問它,而不管它是否已經被獲取 - 理由在於每一種用法,你都不知道數據立即可用或是否需要提取。 –

+0

@ Beetroot-Beetroot你能解釋一下如何使用異步方法訪問已獲取的數據嗎?也許用代碼或僞代碼發佈答案? – Christophe

+0

查看已發佈的答案。這就是這些人試圖解釋的。 –

回答

0

也許創建一個虛假的承諾與$ .when?

var promise; 
if (dictionary) promise = $.when(dictionary); 
else { 
    promise = $.ajax({ 

    }) 
    .done(function(dictionary){ 
     // convert encoded values into names 
    }); 
} 

promise 
    .done(function(){ 
     // run my application 
    }); 
2

您應該只需撥打$.ajax()一次,並將返回的承諾存儲在您的(global-ish)dictionary變量中。

然後,每次你想使用結果,只需寫dictionary.then(...)
如果AJAX請求已經完成,回調將立即運行。

+1

那麼,這不是它的工作原理。正如我在問題中所說的,即使當我的代碼開始時,字典可能已經存在(由不受我控制的另一個腳本加載),在這種情況下,我甚至不需要第一個ajax調用。例如,字典可以存儲在localStorage中。 – Christophe

+0

@Christophe:然後將全局設置爲預先解決的承諾,然後調用'.then()'。 – SLaks

+0

好的,這就是我想要了解的,如何寫出有條件的承諾。 – Christophe

3

這是一種模式我一般用:

var done = function() { 
    //continue loading application 
} 

if(!dictionary) { 
    $.ajax({ 

    }) 
     .done(done); 
} else { 
    done.apply(this); 
} 

一個非常類似的模式,總是利用一個延遲的對象,可能是以下幾點:

var 
    dictionaryDeferred = new $.Deferred(), 
    dictionaryPromise = dictionaryDeferred.promise(); 

if(!dictionary) { 
    $.ajax({ 

    }) 
     .done(function() { 
      //do something with the response 
      dictionaryDeferred.resolve(); 
     }); 
} else { 
    dictionaryDeferred.resolve(); 
} 

dictionaryPromise.then(function() { 
    //continue loading application 
}); 
+0

謝謝。我更喜歡第二種模式,因爲它使連鎖更容易。一個問題可能是字典提示的已解決的值在兩個分支之間不一致(但在我的情況下,字典不是全局變量)。 – Christophe

+0

您不必在可能需要字典的地方使用'dictionaryPromise',如果您願意,您可以在應用程序正在加載的地方使用它,因爲您仍在檢查if(!dictionary )'已經存在或不存在。 – Adam

+0

爲什麼在使用'new'時可以使用$ .Deferred()使用'new'? –