Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/427.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用2个XMLHttpRequest,一个依赖于另一个?_Javascript_Xmlhttprequest - Fatal编程技术网

Javascript 如何使用2个XMLHttpRequest,一个依赖于另一个?

Javascript 如何使用2个XMLHttpRequest,一个依赖于另一个?,javascript,xmlhttprequest,Javascript,Xmlhttprequest,我正在做一个项目,在这个项目中我有两个XMLHttpRequest()对象,比如a和B 我想要完成的是,当A完成获取数据项列表时,B将被触发,以基于A先前获取的数据项获取更多的项 目前我的问题是这两个对象相互独立地工作 我的代码如下: var A = new XMLHttpRequest(); var B = new XMLHttpRequest(); A.open("GET", directory, true);

我正在做一个项目,在这个项目中我有两个XMLHttpRequest()对象,比如a和B

我想要完成的是,当A完成获取数据项列表时,B将被触发,以基于A先前获取的数据项获取更多的项

目前我的问题是这两个对象相互独立地工作

我的代码如下:

            var A = new XMLHttpRequest();

            var B = new XMLHttpRequest();

            A.open("GET", directory, true);
            A.onreadystatechange = function () {

                if (A.readyState === 4) {
                    if (A.status === 200 || A.status == 0) {
                     //does... something
                     }
                }

            }
            A.send(null);
            while(true){

                B.open("GET", another_directory, false);
                B.overrideMimeType("application/document");
                B.send(null);
                if (B.status == "404")
                continue;

                 //does... something else
            }
这段代码不起作用,因为我发现每次B在A完成之前继续。我基本上不知道该使用哪个事件

我怎样才能实现我的目标? 我可以使用哪些事件,以便在完成A后立即同步处理B

(经过长时间编辑后)我强烈建议您花点时间了解JavaScript中异步调用的本质。这里有一些推荐阅读。我认为这很简单,足以理解发生了什么。注意:在“输入Mobl”时停止读取

在JavaScript中,当您调用一个函数时,系统会将该函数放入一个带有隐式指令的“队列”中,以便尽快运行它。它对每个函数调用都这样做。在您的例子中,您告诉系统先运行A,然后运行B。A进入队列,B进入队列。它们作为单独的功能提交。B碰巧先跑

对于普通函数,如果要控制序列,可以将A函数调用嵌套在B函数调用中。但是,哎呀。您正在使用XMLHttpRequest,因此限制了自定义函数的能力。继续读下去。查看“异步调用”一段。看看你的代码

A.onreadystatechange = function () {
    if (A.readyState === 4) {
         if (A.status === 200 || A.status == 0) {
             //does... something
             (RUN ALL THE B.methods right here...)
         }
    }
}
我认为,如果您想要一个无jQuery解决方案,那么这将使您到达目的地

对于那些只想要一个正常运行的系统,不想更好地理解该语言的人,这里有一个jquery解决方案。。。注意B函数调用是如何嵌套在A函数调用中的。请注意,这种嵌套的顺序是基于jQuery成功标记的存在。如果不使用jQuery,则必须根据需要手动嵌套函数

var special_value;
$("button").click(function(){
    $.ajax({url: "demo_testA.html", 
            type: 'GET',
            success: function(resultA){
               special_value = resultA;
               $.ajax({url: "demo_testB.html",
                      type: 'GET', 
                      data: special_value, 
                      success: function(resultB){
                            $("#div1").html(resultB);
               }});
    });
});

我要说的是,通过更好的沟通,帮助你自助会容易得多。如果你不喜欢某样东西,那么就说出来。如果你不明白某些事情,请进一步澄清或编辑你的问题陈述。反馈是一件好事。

好的,让我们从代码开始。我已经添加了一些注释,因此现在您可以了解问题的根源:

var A = new XMLHttpRequest(); //You create an XMLHttpRequest object
var B = new XMLHttpRequest(); //And an another

A.open("GET", directory, true); 

/* Now you open a GET request to DIRECTORY, with async TRUE. The third parameter can 
make a request sync or async, but sync is not recommended as described below. */

A.onreadystatechange = function () {
    if (A.readyState === 4) {
        if (A.status === 200 || A.status == 0) {

        /* So you registered an event listener. It runs when the readyState changes.
        You can use it to detect if the request is finished or not. If the readyState is
        4, then the request is finished, if the status code is 200, then the response is
        OK. Here you can do everythin you want after the request. */

         }
    }

}

A.send(null); //Now you send the request. When it finishes, the event handler will
// do the processing, but the execution won't stop here, it immediately goes to the 
// next function

while(true){ // Infinite loop
     B.open("GET", another_directory, false); //Open request B to ANOTHER_DIRECTORY,
     // but now, request B will be synchronous

     B.overrideMimeType("application/document"); // Configure mime type

     B.send(null); // Send the request

     if (B.status == "404")
         continue;
         // If it's not found, then go to the next iteration

     // and do something else
}
我希望现在你能看到问题的根源。运行此脚本时,您将启动一个异步请求,然后立即启动下一个请求。现在您可以从两种方式中进行选择

从回调运行下一个请求(推荐) 这是更好的方法。因此,启动您的第一个(异步)请求,并在事件侦听器(您在其中进行处理)中启动下一个请求。我在这里做了一个有评论的例子:

(您可以不使用数组进行操作-这只是一个示例)

如果您使用这种方式,那么GUI将不会冻结,直到您等待响应。一切都将负责,所以你可以与网页互动,你可以创建取消按钮,等等

同步AJAX(不推荐) 我不建议这样做,因为在Chrome中“主线程上的同步XMLHttpRequest已被弃用”,但如果您确实想这样做,那么您可以尝试使用此解决方案。因此XMLHttpRequest的open函数有3个参数:

  • 方法:使用哪个HTTP方法ID
  • URL:请求哪个URL
  • 异步:异步请求?如果为false,则它将是同步的,这意味着在调用.send()之后,它将暂停执行,直到响应返回

因此,如果您将第三个参数设置为FALSE,那么您可以轻松地执行此操作。。。但你不应该

这里有一个替代解决方案,使用或,这个问题变得简单得多:

fetch(directory).then(function(response){
    // some processing
    return fetch(another_directory); // can change content type too, see the mdn docs
}).then(function(responseTwo){
      // all processing is done
}).catch(function(err){
      // handle errors from all the steps above at once
});

这与XHR一样是原生的,并且使用Promission进行管理要简单得多

Javascript是异步的。您需要了解回调。。。做一个函数,完成后回调到B函数…这取决于你正在使用的浏览器以及你正在使用的东西是否很快就不能使用,特别是如果这是为你自己,我建议你学习使用
获取
:问题没有标记为jQuery,这个答案并没有给出任何问题的解释或建议的解决方案。哎呀,我认为很明显,问题在于98%理解javascript函数调用,2%使用XMLHttpRequest()。阅读我在原始问题下面的评论。目前还不清楚ikis是否打算采用无jQuery解决方案。查看他对我的解决方案的回复意见。。哎呀。他从未对我三周前的回答提供任何反馈。相反,他在标签上加了一笔赏金(从来没有给我发过信息?呃……为什么不?)。。。你见过标签选择不当的问题吗?(答:一直如此)他可以很容易地在他的问题中没有提到jquery rqmt。当然。但是您的答案并没有提供对(异步)函数调用的任何理解,只是一个jQuery示例片段。有效答案不需要包含XHR,可以包含jQuery;但是它不能依赖jQuery,因此,jQuery解决方案。我试图做出优雅的声明“滚开,学习语言的工作原理”,而我不打算为他嵌套函数(这将花费我大约四分钟的时间)。所以是的,它没有很好地表达这个信息,为此我道歉。但是如果他回嘴(这正是我要找的…),我会给他更多的提示,让他自己去正确的目的地。所以我被降级了。好吧,随便吧。我仍然不会为他做这家伙的(家庭)工作。是的,如果你觉得OP不愿意沟通,就不要回答,继续前进。如果你不打算改进你的帖子,你可能想删除它