JQuery等待变量异步赋值

时间:2017-06-28 10:34:44

标签: javascript jquery ajax asynchronous wait

这个问题已被多次询问,但遗憾的是我无法理解如何继续。

我有一个场景,其中可能需要或可能不需要通过异步调用为变量赋值。

这是代码:

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 - 两种方式完全独立,尽管代码运行在两种情况下实际上是相同的,因此代码重复。

这种方法除了在我看来不是逻辑上最优之外,还增加了代码的不必要的复杂性(因此它的维护),因为从断点开始需要完成的所有事情都需要在至少两个地方完成。

当一张图片等于千言万语时,我还附上了我上面试图描述的流程图,希望它至少能让我的思路清晰:

enter image description here

3 个答案:

答案 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(),让我们在页面加载中说。另一种情况是异步调用完成后。因此,您可以在continueVarprocessContinue()

时添加您想要实施的逻辑

答案 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)。