1

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

我只想script_2script_1完成执行后调用。

这意味着首先我想script_1在 ajax中调用,script_1在其各自的 div 中显示执行结果,然后调用第二个脚本,在第二个 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

4 回答 4

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
于 2012-05-22T14:03:03.943 回答
1

可能您最好的选择是使用 Javascript 库,例如 jQuery。jQuery 具有jQuery.Deferred()可用于轻松表示承诺(未来结果)的对象,从而允许轻松链接函数调用。请注意$.get(),例如,返回 a 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()是 current 的别名pipe()

于 2012-05-22T14:01:29.327 回答
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'));
});

还有更多使用$.getScript().

于 2012-07-18T03:46:22.713 回答
0

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

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

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

于 2012-05-22T13:59:03.660 回答