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

Call multiple scripts through ajax. Script 2 should be called only after Script 1 has finished its execution

本文关键字:脚本 调用 执行 ajax 通过      更新时间:2023-09-26

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

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

这意味着首先我想在 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
    }
}

我不认为这是这样做的正确方法。请建议如何以不太复杂的方式执行此操作。

两个词:抽象和回调:

//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

可能你最好的选择是使用Javascript库,例如jQuery。 jQuery具有jQuery.Deferred()对象,可用于轻松表示承诺(未来结果(,从而允许轻松链接函数调用。请注意,例如,$.get() 返回一个Deferred(请参阅页面中的以下文档(。本文也有一个很好的解决方案和一个有效的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()的别名(

你可以

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

$.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'));
});

还有更多使用 $.getScript() 的示例。

实际上非常合适(想法(,您当然可以在 ajax 调用中使用 jQuery 及其异步选项来强制同步 (http://api.jquery.com/jQuery.ajax/(,或者通过使用回调处理在我们的代码中做success()同样的事情。

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

第三种选择是您使用setTimeout()/clearTimeout()实现或setInterval()强制同步模式,但这不是我推荐的方式。