2013-09-30 62 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'? –