如何在调用Ajax之类的异步调用时使代码等待

the*_*ack 90 javascript jquery

我正在寻找这样的东西

function someFunc() {

callAjaxfunc(); //may have multiple ajax calls in this function
someWait(); // some code which waits until async calls complete
console.log('Pass2');

}

function callAjaxfunc() {
  //All ajax calls called here
  console.log('Pass1');

}
Run Code Online (Sandbox Code Playgroud)

我试过了什么?

1 Jquery.when()

尝试使用它..工作正常.但不是我想要的方式.$.when将等待,但旁边的代码$.when()运行没有等待.里面的代码do callback只在ajax调用之后运行

2. setTimeOut()带有全局标志

我非常有信心这会奏效.我试过跟随.

GlobalFlag = false;

function someFunc()     
    callAjaxfunc(); //may have multiple ajax calls in this function
    setTimeOut(waitFunc, 100); // some  which waits until async calls complete
    console.log('Pass2');
}

function callAjaxfunc() {
    //All ajax calls called here
    onAjaxSuccess: function() {
        GlobalFlag = true;
    };
    console.log('Pass1');    
}

function waitFunc() {
    if (!GlobalFlag) {
        setTimeOut(waitFunc, 100);
    }
}?
Run Code Online (Sandbox Code Playgroud)

仍然无法得到想要的结果.我在这里做错了吗?这不是办法吗?

我想要的结果应该是这样的

Pass1
Pass2
Run Code Online (Sandbox Code Playgroud)

因为需要AJAX调用所以无法做任何小提琴

编辑:许多人建议回调.. somewait()我知道他们..但是旁边的代码仍然会被执行...我希望浏览器完全停止执行代码,somewait()直到ajax调用..这也许是一个不好的做法但值得知道并尽可能尝试......

Dog*_*ert 56

使用回调.这样的事情应该基于您的示例代码.

function someFunc() {

callAjaxfunc(function() {
    console.log('Pass2');
});

}

function callAjaxfunc(callback) {
    //All ajax calls called here
    onAjaxSuccess: function() {
        callback();
    };
    console.log('Pass1');    
}
Run Code Online (Sandbox Code Playgroud)

这将Pass1立即打印(假设ajax请求至少需要几微秒),然后Pass2onAjaxSuccess执行时打印.

  • 我知道回调...基本的方式...但在这里我想停止浏览器做任何事情..直到Ajax调用完成.. (8认同)
  • 事情是使用一些propreitory框架..有页面开始加载的加载功能和页面加载之前我需要获取数据,只有我可以覆盖的功能是加载功能... (3认同)
  • @CodeJack,我认为这不可能在javascript中.你想通过这样做实现什么,这是不是这样做的?(即将代码移动到回调中). (2认同)

Ale*_*der 17

为什么它不适合你使用Deferred Objects?除非我误解了一些可能对你有用的东西.

/* AJAX success handler */
var echo = function() {
    console.log('Pass1');
};

var pass = function() {
  $.when(
    /* AJAX requests */
    $.post("/echo/json/", { delay: 1 }, echo),
    $.post("/echo/json/", { delay: 2 }, echo),
    $.post("/echo/json/", { delay: 3 }, echo)
  ).then(function() {
    /* Run after all AJAX */
    console.log('Pass2');
  });
};?
Run Code Online (Sandbox Code Playgroud)

在这里看到它.


UPDATE

根据您的输入,似乎最快的替代方法是使用同步请求.您可以将属性设置asyncfalse您的$.ajax请求,使它们阻塞.这将挂起您的浏览器,直到请求完成为止.

请注意,我不建议这样做,我仍然认为您应该在基于事件的工作流程中修复代码,而不是依赖它.

  • @CodeJack,如果您仍然想使用它,请在要阻止的 AJAX 调用中将 [`async`](http://api.jquery.com/jQuery.ajax/) 设置为 `false` (2认同)

Ama*_*dan 9

真正的程序员用信号量来做.

设置变量0.在每次AJAX调用之前递增它.在每个成功处理程序中减少它,并测试0.如果是的话,你就完成了.

  • 信号量是编程语言中不可用的东西...... (3认同)
  • @CodeJack:正如我上面的评论所提到的,信号量绝对适用于JavaScript.由于没有并发,JavaScript没有的概念是*lock*.信号量只是美化的计数器,通常与锁一起使用(因为在多线程环境中你绝对需要它们). (3认同)
  • 像关键部分这样的信号量是允许线程/进程之间安全共享资源的技术.我觉得你对这个词很困惑.正如@CodeJack所说,这种对象在Javascript中不可用,但如果可以的话,它们将不适用于这种情况. (2认同)
  • @HMarioD:我很困惑?http://en.wikipedia.org/wiki/Asynchronous_semaphore - 特别注意*所有示例都在JavaScript*中. (2认同)