通过ajax调用多个脚本。只有在脚本1完成执行后才应调用脚本2

时间:2012-05-22 13:44:11

标签: javascript ajax

我有4个脚本,我想通过ajax一个接一个地调用。

我想在script_2完成执行后才调用script_1

这意味着首先我要在ajax中调用script_1,在其各自的div中显示script_1执行的结果,然后调用第二个脚本,在第二个div中显示其结果,依此类推。

目前我正在做的是在onreadystatechange()函数内创建一个新的ajax调用(以嵌套的方式)。

以下是伪代码:

var script1_ajax = new XMLHttpRequest();

script1_ajax.onreadystatechange=function() {            
    if (script1_ajax.readyState==4 && script1_ajax.status==200) {

        document.getElementById('result').innerHTML = script1_ajax.responseText;
        //create second ajax request and call it
        //similarly create two more nested ajax calls and call it
    }
}

我认为这不是正确的做法。 请以不太复杂的方式建议如何做到这一点。

4 个答案:

答案 0 :(得分:2)

用两个词来说:抽象和回调:

//abstract the AJAX code
function ajax(url,data,callback){
    var xhr = new XHR(...
    //the rest of the AJAX setup here
    xhr.onreadystatechange=function() {            
        if (xhr.readyState === 4 && xhr.status === 200) {
            callback(xhr.responseText); //execute callback
        }
    }
    xhr.send();
}

function script1(){
    //call ajax
    ajax('test1.php','somedata',function(returndata){
        //this callback gets executed when ajax is done
        document.getElementById('result').innerHTML = returndata;
        //execute next
        script2();
    });
}

function script2(){
    ajax('test1.php','somedata',function(returndata){
        document.getElementById('result').innerHTML = returndata;
        script3();
    });
}

function script3(){
    //and so on...
}

script1(); //execute first

另一方面,你可以使用jQuery.ajax,它看起来几乎一样:

function script1(){
    $.get('url','data',function(data){
        $('#result').html(data);
        script2();
    });
}

function script2(){
    $.get('url','data',function(data){
        $('#result').html(data);
        script3();
    });
}

function script3(){
    //and so on
}

script1(); //execute first

答案 1 :(得分:1)

可能你最好的选择是使用Javascript库,例如jQuery。 jQuery具有jQuery.Deferred()对象,可用于轻松表示promise(未来结果),从而允许轻松链接函数调用。请注意,$.get()例如返回Deferred(请参阅下面的文档)。 This article也有一个很好的解决方案和一个有效的jsfiddle,但它与Deferred方法不同,这只是一个问题

function _get(url, params, success) {
  return function() {
    return $.get(url, params, success);
  }
}

$.get("http://host/1", {}, updateDiv)   // see the doc for $.get()
  .pipe(_get("http://host/2"))          // see $.Deferred() and pipe()
  .pipe(_get("http://host/3"))
  .pipe(_get("http://host/4"));

如果您不了解jQuery,$.get(url, params, callback)是进行异步HTTP GET请求的方法

注意:我更新了代码,因为deferred.then()需要回调(我给了它一个承诺)并将then()替换为pipe(),这样可以提供当前的预期行为jQuery版本(实际上在1.8中似乎then()是当前pipe()的别名)

答案 2 :(得分:1)

你可以这样做。假设您必须加载三个脚本,第三个脚本有回调。

$.get("js/ext/flowplayer-3.2.8.min.js")
.pipe($.get("js/eviflowplayer.js"))
.pipe($.get("js/evi.flowplayer.js", {}, function()
{
    W.EVI.FLOWPLAYER.init(elem.attr('id'));
});

more examples使用$.getScript()

答案 3 :(得分:0)

实际上是非常合适的(想法),你当然可以在ajax调用中使用jQuery及其async选项来强制它同步(http://api.jquery.com/jQuery.ajax/),或者使用{在我们的代码中执行相同的操作{1}}回调处理。

对于此请求的代码,我确定您知道它在某些浏览器上失败了吗?它看起来很糟糕,因为你需要两次调用相同的函数集,尝试将它们放入函数中,也许在一些类/ JSON中包装整个ajax请求。

第三个选项是您自己强制执行success() / setTimeout()实施或clearTimeout()同步模式,但这不是我推荐的方式。