如何让代码在调用像 Ajax 这样的异步调用时等待

我在找这样的东西

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');


}

我尝试了什么?

1 Jquery.when ()

tried using it..it works fine. But not the way I want. $.when will wait but the code next to $.when() runs with out waiting. The code inside do callback only runs after ajax calls

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);
}
}​

还是得不到想要的结果。我是不是做错了什么? 这不是正确的方式吗?

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

Pass1
Pass2

由于需要 AJAX 调用,因此无法进行任何操作

EDIT: As many were suggesting callbacks..i know about them..but still the code next to somewait() will get executed...I want browser to completely stop executing code next to somewait() until the ajax call..Also it may be a bad practice but worth to know and try if possible...

250947 次浏览

Real programmers do it with semaphores.

Have a variable set to 0. Increment it before each AJAX call. Decrement it in each success handler, and test for 0. If it is, you're done.

Use callbacks. Something like this should work based on your sample code.

function someFunc() {


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


}


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

This will print Pass1 immediately (assuming ajax request takes atleast a few microseconds), then print Pass2 when the onAjaxSuccess is executed.

Why didn't it work for you using Deferred Objects? Unless I misunderstood something this may work for you.

/* 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');
});
};​

See it here.


UPDATE

Based on your input it seems what your quickest alternative is to use synchronous requests. You can set the property async to false in your $.ajax requests to make them blocking. This will hang your browser until the request is finished though.

Notice I don't recommend this and I still consider you should fix your code in an event-based workflow to not depend on it.

If you need wait until the ajax call is completed all do you need is make your call synchronously.