在Javascript中等待异步函数调用的最有效方法是什么?

时间:2012-03-08 08:57:16

标签: javascript

这可能与my previous question here相反,但无论如何,我也需要知道答案。

我的算法中有一个Ajax调用,我需要等待它运行一些代码。有两种解决方案:

1)典型的解决方案:

ajaxCall(function(result){
  //the code to run after the call is returned
});

2)我想知道它是否可以替代:

res=null;
ajaxCall(function(result){
  res=result;
});
while(res==null)/*wait! but this will lock the GUI I guess*/;
//do the rest of the code because now res is initialized

问题是如何以一种不会冻结GUI的有效方式编写第二种解决方案?

5 个答案:

答案 0 :(得分:2)

我建议将所有依赖代码挂钩,以作为ajax调用返回的回调执行。这样,所有其他javascript可以继续执行,并且您不会在通话期间使浏览器无响应。

或者,这不是我永远不会做的事情,你可以使用async: false来同步你的ajax调用:

$.ajax({ url: ..., async: false });

答案 1 :(得分:2)

只需将ajax调用同步。

参考:http://developer.mozilla.org/en/XMLHttpRequest

查找async参数

答案 2 :(得分:1)

一般答案:

异步中只有两种方法可用。编程:事件和回调。周期。

(从技术上讲,两者在最低级别上并没有真正区别,“事件”只是一个(库)函数 - 执行事件“触发”的人 - 执行注册为的所有函数监听器所以它与回调相同 - 从技术上讲,即当你编写event.fire()或者你喜欢的lib的事件语法时,它是所有已注册事件处理函数的同步调用。何时使用其中一个是设计API时的偏好,约定和样式。)

答案 3 :(得分:1)

Javascript编程,尤其是AJAX,根据定义是异步的。因此,如果您有一个需要“等待”某事的算法,那么最好重新考虑该算法。具有讽刺意味的是,Javascript语法不是最适合异步编程,但有许多库可以帮助您控制回调并避免使用意大利面条代码。

回调示例:

function ajaxRequest(url1, function() {
    animateSomething(div, function() {
        ajaxRequest(url2, function() {
            ....
        })
    })
})

async.js相同,看起来更清晰:

async.series([
    function(_) { ajaxRequest(url1, _) },
    function(_) { animateSomething(div, _) },
    function(_) { ajaxRequest(url2, _) }
])

答案 4 :(得分:0)

有很多方法可以做到这一点。其中一个是将回调传递给ajax(或至少是它的引用)。你的代码#1就是一个例子。

另一个是你有一个通知符对象,你可以向它添加ajax成功调用。然后你可以插入其他功能(一个或多个)来听取“成功”公告。