【问题标题】:AJAX with callback function带有回调函数的 AJAX
【发布时间】:2015-09-13 12:13:53
【问题描述】:

我们怎样才能让异步函数停止并等待响应? 我从How do I return the response from an asynchronous call? 获得了一些关于从异步函数中获取值的解决方案但是,如果我们必须将一些值传递给函数,我仍然有更多关于如何从异步函数中获取值的问题。

在这里,我有 3 个功能。一、异步函数。

 function getVal(param,callbackFunc)
 {
     a = function()
     {
       if(a.state==finished)
             callbackFunc(a.response);
     };
 }

这个是回调函数

 handler(result)
 {
    return result;
 }

而且,这是我调用异步函数的地方,也是我遇到问题的地方

function core()
{
  for(var i = 0 ; i < 10 ; i ++)
  {
    getVal(g[i],handler);
  }
}

如您所见,我发送给 getVal 函数的参数是一个数组。那么问题来了,如何让 getVal 函数同步执行参数。

这总是给我数组的最后一个成员的结果(看起来函数跳过了从 g[0] 到 g[9] 的所有值。它总是返回 getVal(g[10],handler) 的值) .

请帮忙

谢谢。

【问题讨论】:

  • 我觉得你的脚本中遗漏了一些重要的东西,以便我们理解你的问题,但我猜你正在寻找的解决方案是stackoverflow.com/a/1676422/3820185
  • 好吧,如果您仔细阅读链接到的问题,您会发现您无法从异步调用返回响应。这是并发模型的固有部分。您只能返回一个承诺或接受一个回调。如果你使用 ES2016 async/await 语法,你可以接近,生成器也不错,但仅此而已。
  • 如果我把异步函数分离到一个类中,调用实例而不是直接调用函数呢?
  • 你在问相当于“给我找一个一直违法但又不是罪犯的人”。不等待返回值是异步的定义的一部分。
  • @JaredSmith:答案是“政治家”。

标签: javascript jquery ajax asynchronous dhtml


【解决方案1】:

您的问题与 Ajax 没有直接关系,只要代码块的执行延迟就会发生。以下代码 sn-ps 使用计时器重现了这种情况。最后一个代码 sn -p 是您问题的可能解决方案。顺便说一句,如果您仍然对 Ajax 感到困惑,这里尝试使其易于理解:https://stackoverflow.com/a/32163917/1636522


无延迟:i 立即打印。

print('loop start');
for (var i = 0; i < 3; i++) {
  print(i);
}
print('loop end');

function print (html) {
  document.body.innerHTML += html + '<br />';
}

1 秒延迟:打印动作在 1 秒后执行,但 "for" 循环继续进行,因此,i 在打印之前达到 3。

print('loop start');
for (var i = 0; i < 3; i++) {
  setTimeout(function () {
    print(i);
  }, 1000);
}
print('loop end');

function print (html) {
  document.body.innerHTML += html + '<br />';
}

1 秒延迟 + 持久性: i 被复制到一个新变量中。此变量是自调用函数的本地变量,并且在调用打印函数时仍然存在。

print('loop start');
for (var i = 0; i < 3; i++) {
  (function (copy) {
    setTimeout(function () {
      print(copy);
    }, 1000);
  })(i);
}
print('loop end');

function print (html) {
  document.body.innerHTML += html + '<br />';
}

【讨论】:

    【解决方案2】:

    一种方法是使 ajax 请求同步。

    var xhr =new XMLHttpRequest();
    xhr.open("GET","url", false);
    

    此处设置为 False 将确保在没有得到响应之前不会运行其余代码。

    否则我要做的是发出所有异步请求,然后在每次响应时从 array.length 中减去 1 并检查它是否为零。如果是,则表示我们已收到所有响应,因此请调用回调。

    【讨论】:

    • 尝试您的解决方案后收到警告!!! “主线程上的同步 XMLHttpRequest 已被弃用,因为它对最终用户的体验产生不利影响。如需更多帮助,请查看 xhr.spec.whatwg.org。”
    • 是的,它说这不是一个好习惯。因此,出于哪些原因,我还认为您最好创建一个变量,例如 Left,然后使其等于数组的长度。然后每次你从它得到响应减 1。并且在每个响应中还要检查它是否是 Left==0 然后如果是那么你就知道你已经完成了
    猜你喜欢
    • 2011-06-26
    • 2011-11-28
    • 1970-01-01
    • 2011-11-15
    • 1970-01-01
    • 1970-01-01
    • 2015-08-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多