Javascript 在继续执行单独的函数之前等待 AJAX

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11289884/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 05:18:40  来源:igfitidea点击:

Wait for AJAX before continuing through separate function

javascriptcodeigniterjquery

提问by glassfish

Alright... at 2am, this is where I draw the line. Help... before my laptop ends up going out the window. :)

好吧……凌晨 2 点,这是我划线的地方。帮助...在我的笔记本电脑最终走出窗外之前。:)

I've tried using setTimer, callbacks, and everything else I can think of (along with a few other Stackoverflow hints of course). I've stripped out everything so I'm leaving just the base code.

我尝试过使用 setTimer、回调和我能想到的所有其他东西(当然还有其他一些 Stackoverflow 提示)。我已经删除了所有内容,所以我只留下基本代码。

What I'm looking to do is call parseRow() and before it saves the record at the end, I need to grab the associated Category (via AJAX); however, it blows right past it so category is always "undefined".

我想要做的是调用 parseRow() 并且在它最后保存记录之前,我需要获取关联的类别(通过 AJAX);然而,它吹过了它所以类别总是“未定义”。

function parseRow(row){
    var rowArray     = row.trim().split(",");
    var date         = rowArray[0];
    var checknum     = rowArray[1];
    var payee        = rowArray[2];
    var memo         = rowArray[3];
    var amount       = rowArray[4];

    //ERROR: blows right past this one and sets the category variable BEFORE ajax returns
    var category = autoSelectCategory(payee);

    saveRecord(date, checkNum, payee, memo, category, payment, deposit);
}

function autoSelectCategory(payee) {
    var data;
    $.ajax({
        async: false,
        url: "autoselectcategory",
        dataType: "json",
        data: {
            string: payee
        },
        success: function (returnedData) {
            data = returnedData;
        }
    });
    return data;
}

回答by penartur

AJAX stands for asynchronous. That means that in your original code, saveRecordwill be executed beforethe client will receive the response from the server (and, depending on the $.ajaximplementation, it might be before the client will send the request to the server).

AJAX 代表异步。这意味着在您的原始代码中,saveRecord将在客户端从服务器接收响应之前执行(并且,根据$.ajax实现,它可能在客户端将请求发送到服务器之前执行)。

Additionally, you seem to misunderstand how functions work in JS. var category = autoSelectCategory(payee);will set the category to the return value of autoSelectCategory; but the autoSelectCategoryfunction in your code returns nothing.

此外,您似乎误解了函数在 JS 中的工作方式。var category = autoSelectCategory(payee);将类别设置为的返回值autoSelectCategory;但是autoSelectCategory您代码中的函数不返回任何内容。

From the other side, the datareturn value of your anonymous function could only be used by $.ajaxfunction (and $.ajaxlikely ignores the successparameter return value).

另一方面,data匿名函数的返回值只能由$.ajax函数使用(并且$.ajax可能会忽略success参数返回值)。

Here is the code that should work:

这是应该工作的代码:

function parseRow(row){
    var rowArray     = row.trim().split(",");
    var date         = rowArray[0];
    var checknum     = rowArray[1];
    var payee        = rowArray[2];
    var memo         = rowArray[3];
    var amount       = rowArray[4];

    autoSelectCategory(payee, function (category) {    
        saveRecord(date, checkNum, payee, memo, category, payment, deposit);
    });
}

function autoSelectCategory(payee, callback) {
    $.ajax({
        async: false,
        url: "autoselectcategory",
        dataType: "json",
        data: {
            string: payee
        },
        success: callback
    });
}

回答by freakish

Do not use async: falseoption. It's a pure evil (blocks allscripts in browser and even other tabs!) and it's deprecated since jQuery 1.8. You should use callbacks as it was always meant to be.

不要使用async: false选项。这是一个纯粹的邪恶(阻止浏览器甚至其他选项卡中的所有脚本!)并且它自 jQuery 1.8 以来已被弃用。您应该使用回调,因为它一直都是如此。

function parseRow(row) {
    /* the other code */
    autoSelectCategory(payee, function() {
        saveRecord(date, checkNum, payee, memo, category, payment, deposit);
    });
}

function autoSelectCategory(payee, callback) { // <---- note the additional arg
    $.ajax({
        url: "autoselectcategory",
        dataType: "json",
        data: {
            string: payee
        },
        success: function(res) {
            /* the other code */
            callback();
        }
    });
}