如何避免这种异步懒惰模式?

Rém*_*ghe 6 javascript asynchronous promise

很多时候,我需要在Javascript中编写这样一个懒惰的异步加载:

if (myvar != undefined){
    doSomeTreatment(myvar)
} else {
    loadMyVarAsynchronously().then(function(value){
        myvar = value
        doSomeTreatment(myvar)
    })
}
Run Code Online (Sandbox Code Playgroud)

在这里,myvar将是哈希的一些属性,而不是局部变量.loadMyVarAsynchronously以异步方式加载myvar的值(例如,a Promise或a JQuery Deferred)

是否有一种模式可以避免在此代码中写入以下两行?

doSomeTreatment(myvar)
Run Code Online (Sandbox Code Playgroud)

Geo*_*uer 1

如果没有具体的、现实的例子,真的很难推理出你在这里所做的事情。这绝对不是我在代码中经常使用的模式,因此我怀疑您可以通过重新评估您的假设来解决它。

话虽如此,您可以使用承诺链。请注意,在这种情况下,promiseThatLoadsVar 是一个承诺,它不是一个返回承诺的函数。这意味着它维护一个状态,并且该代码第二次运行时它将立即返回。

promisethatLoadsVar.then(function(value) {
     myvar = value;
     doSomeTreatment(myvar);
})
Run Code Online (Sandbox Code Playgroud)

如果您能提出更明确的问题,我很乐意为您提供更明确的答案。

编辑:我想详细说明评论中提出的示例。这是使用LoDash库的解决方案。(顺便说一句,你应该使用lodash或underscore,它们基本上是javascript的标准库)。

var getData = _.once(function() { return $.getJSON(...) });

$('button').on('click', function() { 
    getData().then(function(data) { showDialog(data) }) 
})
Run Code Online (Sandbox Code Playgroud)

请注意,这getData是一个包装函数,在第一次调用后将一遍又一遍地返回相同的内容,而无需重新调用该函数。第一次调用它时,它将返回一个在检索数据时解析的承诺。第二次你会得到同样的承诺,而这个承诺很可能已经得到解决。

您想将参数传递给 吗getData

var getData = _.memoize(function(id) { return $.getJSON(url+id) });

$('button').on('click', function() { 
    getData($('#selector').val()).then(function(data) { showDialog(data) }) 
})
Run Code Online (Sandbox Code Playgroud)

这将做同样的事情,但是通过传递给 的第一个输入参数缓存承诺getData