javascript 我怎样才能等到我的 AJAX 请求完成?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19066733/
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-10-27 14:13:59  来源:igfitidea点击:

How can I wait until my AJAX request is complete?

javascriptajaxjquery

提问by njp

So, I have an init function that runs when the DOM is fully loaded:

所以,我有一个在 DOM 完全加载时运行的 init 函数:

function init() 
{
    TerrainObj.load_terrain();
    TerrainObj.generate_display_layer(PlayerObj);
    GameObj.update();
    ScreenObj.draw_screen(TerrainObj);
    ScreenObj.update_screen(TerrainObj);
    mainloop();
}

The very first method, TerrainObj.load_terrain(), makes an AJAX requestL:

第一个方法,TerrainObj.load_terrain(),发出一个 AJAX 请求:

load_terrain: function()
{
    var settings = {
        type: "GET",
        url: "data/map.txt",
        aysnc: false
    };

    $.ajax(settings).done(function(result) 
    {
        this.terrain = result.split("\n");
        for (var i = 0; i < this.terrain.length; i++)
        {
            this.terrain[i] = this.terrain[i].split("")
        }
        console.log(this.terrain);
    });
}

The problem is that, in our init()function, most of the methods that follow TerrainObj.load_terrain()require the presence of the TerrainObj.terrain array, but they are called before the AJAX request can complete and that variable is populated. I put a little message out when each function runs to check the order, and I get this:

问题是,在我们的init()函数中,后面的大多数方法都TerrainObj.load_terrain()需要存在TerrainObj.terrain array,但是它们在 AJAX 请求可以完成并填充该变量之前被调用。当每个函数运行以检查订单时,我会发出一条消息,我得到了这个:

Ran TerrainObj.load_terrain()
Ran ScreenObj.draw_screen()
Uncaught TypeError: Cannot read property '0' of undefined 
[Array[55], Array[55], ... ]

So as you can probably see, ScreenObj.draw_screen, which needs TerrainObj.terrain, has run before the request can complete, and there's a TypeErrorwhen it tries to reference our object. It's not ready yet! The very last message is the console.log()from the load_terrainmethod, indicating that the .donefunction runs afterwards.

因此,正如您可能看到的,ScreenObj.draw_screen需要 TerrainObj.terrain 的 已在请求完成之前运行,并且有一个TypeError当它尝试引用我们的对象时。还没准备好!最后一条消息是console.log()来自load_terrain方法的消息,表明该.done函数随后运行。

What can I do to wait until the AJAX request is complete before continuing on with my program?

在继续执行我的程序之前,我该怎么做才能等到 AJAX 请求完成?

回答by Lorenz Meyer

Javascript is an event driven language. You do not have a mainloop, but you have events that trigger what is happening.

Javascript 是一种事件驱动语言。您没有主循环,但您有触发正在发生的事情的事件。

Here, the completion of your ajax call triggers the subsquent setting up of the terrain. Thus separate the function in two :

在这里,ajax 调用的完成触发了地形的后续设置。因此将功能分为两部分:

init: function() 
{
    TerrainObj.load_terrain();
},
init_terrain: function()
{
    TerrainObj.generate_display_layer(PlayerObj);
    GameObj.update();
    ScreenObj.draw_screen(TerrainObj);
    ScreenObj.update_screen(TerrainObj);
    mainloop();
},
load_terrain: function()
{
    var settings = {
        type: "GET",
        url: "data/map.txt",
        aysnc: false
    };

    $.ajax(settings).done(function(result) 
    {
        this.terrain = result.split("\n");
        for (var i = 0; i < this.terrain.length; i++)
        {
            this.terrain[i] = this.terrain[i].split("")
        }
        this.init_terrain();
    });
}

回答by Justin Russo

Check the comment section in the below block of code

检查下面代码块中的注释部分

    $.ajax(settings).done(function(result) 
    {
        this.terrain = result.split("\n");
        for (var i = 0; i < this.terrain.length; i++)
        {
            this.terrain[i] = this.terrain[i].split("")
        }
        /*******************************************/
        //Place a new function call here, to the function that contains the calls to your 
        //functions, or other logic, that require the array to be populated.
        /*******************************************/
    });