【问题标题】:Let async ajax with loop finish before further codes get run [duplicate]在进一步的代码运行之前让带有循环的异步ajax完成[重复]
【发布时间】:2022-02-15 10:35:02
【问题描述】:
getUsers();

function getUsers(){
    console.log('Start');

    $.ajax({
        url: 'https://jsonplaceholder.typicode.com/users',
        method: 'GET',
        dataType: 'json',
        success: function (data) {
                data.forEach(user => {
                    console.log(user.id);
                 });                    
        },
        error: function () {
            console.log(data.status);
        }
        
    })

    console.log('End');    
}

上面的代码示例应该打印以下内容: 开始 身份证 ... 结束

但是它有以下问题: 数据的打印顺序错误。它打印 开始 结尾 数据对象

我知道这与异步有关,但我无法解决问题。我尝试了很多东西,比如 $.When() 承诺 异步/等待 但他们都没有帮助。

那么你能告诉我如何解决这个问题吗?

提前谢谢你

【问题讨论】:

  • 据我所知,数据没有属性成功。所以你正在检查不存在的东西(data.success),所以它会转到 if 的另一个分支。它适用于 dataType: json,将 console.log(data) 放在 if 之前,您会看到响应,其中包含您期望的所有数据。
  • dataType 应该是文档中指定的字符串之一,即 xml、json、jsonp、html、脚本等,没有任何建议您在其中放置 mime 类型......文档没有说明什么如果你使用其他东西会发生,我假设它使用默认的“智能猜测”逻辑
  • It prints Start End data-object - 因为ajax 中的第一个a 代表asynchronous - 所以,是的,end 在请求完成之前记录 - 那是异步
  • 现在我已经更正了代码。现在它打印数据。正如我在帖子中提到的,我知道 ajax 是异步的,并且我尝试了很多解决方案。但我无法修复它。
  • 您尝试了哪些方法,但没有成功?添加.done(() => console.log("End")) 就像在this answer 中一样,我会这样做,但还有很多其他选择

标签: javascript ajax asynchronous foreach


【解决方案1】:

Ajax 是异步的,successerror 函数将在稍后服务器响应客户端时调用。这就是为什么有时您会在最后一个console.log 语句中看到data.status 显示在End 之前的原因。其次,您从响应中获得的数据不包含字段success。成功回调函数获得三个参数: 从服务器返回的数据,根据dataTypeparameter 或dataFilter 回调函数(如果指定)格式化; string 描述状态;和jqXHTobject。在您的代码中,您只是将第一个参数传递给它,它是从服务器返回的数据。

【讨论】:

  • 感谢您的回复。正如我所写,我尝试了一切,但我无法解决问题。现在我的问题被标记为已关闭,我无法理解。因此,如果您能展示如何解决问题,那将非常有帮助。
  • 数据没有成功属性。或者一个结果。任何一个。将 dataType 改回 json 并将其设为您的成功函数:success: function (data) {data.forEach(user => {console.log(user.id)})} 并告诉我这是否符合您的要求。
  • @ChrisStricland 谢谢你的回答。这个问题解决了,我已经更正了代码。以上。最大的问题是打印顺序错误。正如我所说,我知道问题与异步有关。但我无法修复它。因此,如果您对此有解决方案,那就太好了。再次感谢。
  • 根据定义,您不能保证异步事件的顺序。您要么将其更改为同步,要么将 Start 和 End 移动到成功函数中。
  • @ChrisStrickland 现在它可以很好地与.done(() => console.log('End')) 或@Phil 回答的其他样式.done(function() {console.log('End')}) 一起使用。感谢您的帮助。
猜你喜欢
  • 2022-12-10
  • 2020-12-02
  • 1970-01-01
  • 1970-01-01
  • 2018-03-06
  • 2016-11-30
  • 1970-01-01
  • 2017-01-31
  • 1970-01-01
相关资源
最近更新 更多