这个问题已被多次询问,但遗憾的是我无法理解如何继续。
我有一个场景,其中可能需要或可能不需要通过异步调用为变量赋值。
这是代码:
var continueFlag = someCondition ? true : false;
if(needToDoAjaxCallFirst){
$.post(someUrl, someData, function(response){
if(response == 'continue')
continueFlag = true;
});
}
/*
If the async call needed to be executed, then this
needs to be executed AFTER the async call is completed:
*/
if(continueFlag){
doStuff(); //do stuff here, regardless of whether the async call needed to be executed or not
}
因此,如果需要运行异步调用,我需要等到它完成后再继续if(continueFlag){
部分。
通常我只是将if(continueFlag){
部分放在异步回调函数中。但是在这种情况下的问题是,即使异步调用不是,也可能需要执行代码。
如果我理解正确,我需要使用Promise来实现这一点。但是,如果情况确实如此,我就不明白究竟是怎么回事。
更新 - 我正在努力避免的一种方法:
var continueFlag = someCondition ? true : false;
if(needToDoAjaxCallFirst){
$.post(someUrl, someData, function(response){
if(response == 'continue')
continueFlag = true;
doStuff();
});
}
/*
If the async call needed to be executed, then this
needs to be executed AFTER the async call is completed:
*/
if(continueFlag){
doStuff();
}
以下评论中的许多人都认为这种方法是最佳解决方案 - 这确实是我在提出问题之前实施它的方式。
但是,我不认为这是一种解决问题的简洁方法,因为在这种情况下最终要执行的代码是相同的,因此我认为代码重复也不合逻辑:它创建了一个断点从那一点开始,代码的过程被分成两个独立的“线程”/“分支”,这取决于是否需要异步调用:if async call needed then go this way, else go that way
- 两种方式完全独立,尽管代码运行在两种情况下实际上是相同的,因此代码重复。
这种方法除了在我看来不是逻辑上最优之外,还增加了代码的不必要的复杂性(因此它的维护),因为从断点开始需要完成的所有事情都需要在至少两个地方完成。
当一张图片等于千言万语时,我还附上了我上面试图描述的流程图,希望它至少能让我的思路清晰:
答案 0 :(得分:2)
首先,您应该避免使用保留的javascript关键字。其次,您可以创建一个在异步调用完成时运行的公共函数,如此
var continueVar = someCondition ? true : false;
if(needToDoAjaxCallFirst){
$.post(someUrl, someData, function(response){
if(response == 'continue')
continueVar = true;
processContinue();
});
}
/*
If the async call needed to be executed, then this
needs to be executed AFTER the async call is completed:
*/
if(continueVar){
processContinue();
}
在你提到的两种情况下,都会在不等待异步完成的情况下调用processContinue()
,让我们在页面加载中说。另一种情况是异步调用完成后。因此,您可以在continueVar
内processContinue()
答案 1 :(得分:1)
没有承诺你总是可以这样写:
var continueFlag = someCondition ? true : false;
if(needToDoAjaxCallFirst){
$.post(someUrl, someData, function(response){
if(response == 'continue')
continueFlag = true;
if(continueFlag){
//if async call needed
}
});
}
else
{
if(continueFlag){
//if there is no need to async call
}
}
答案 2 :(得分:1)
无论您的功能是什么,请将其包装在返回承诺的函数中。您的异步回调中的resolve
或直接适当的
function someFunction(){
return new Promise(function(resolve,reject){
if(needToDoAjaxCallFirst){
$.post(someUrl, someData, function(response){
if(response == 'continue')
resolve();
});
}
else{
resolve();
}
});
}
用法:
someFunction().then(function(){
// this gets called either straight away, or after the ajax response
});
如果您需要将某些内容传递给来电者,您也可以选择适当的reject
,以及resolve
和param(s)。