XHR OnLoad Promise阻止其他OnLoad回调

时间:2015-06-02 10:16:21

标签: javascript asynchronous xmlhttprequest es6-promise

我正在尝试从我的服务器下载文件,然后在加载的数据上运行Promises。 我的问题似乎是我的承诺因某些原因阻止了所有事情:

开始下载所有文件,下载第一个文件后,它会阻止其他文件下载并运行其“onLoad”回调完全保证链,然后继续下载剩余文件。新文件完成后,它会阻止其他下载并运行承诺链等等。

我的onload回调包含以下内容:

function(response) {

  window.console.log('on load callback...');

      var sequence = Promise.resolve();
      sequence
      .then(function(){
        sleep(10000);
        window.console.log('sleep 1 is over...');
        return 'DONE!';
      })
      .then(function(){
        sleep(10000);
        window.console.log('sleep 2 is over...');
        return 'DONE!';
      })
      .then(function(){
        sleep(10000);
        window.console.log('sleep 3 is over...');
        return 'DONE!';
      });
}

我的睡眠功能如下:

 function sleep(milliseconds) {
   var start = new Date().getTime();
   for (var i = 0; i < 1e7; i++) {
     if ((new Date().getTime() - start) > milliseconds){
       break;
    }
  }
 }

在控制台中它返回:

on load callback...
sleep 1 is over...
sleep 2 is over...
sleep 3 is over...
on load callback...
sleep 1 is over...
sleep 2 is over...
sleep 3 is over...
on load callback...
sleep 1 is over...
sleep 2 is over...
sleep 3 is over...
on load callback...
sleep 1 is over...
sleep 2 is over...
sleep 3 is over...

任何帮助都将不胜感激。

我可以理解,当“睡眠”运行时,下载被阻止,但我没有得到的是为什么它在继续下载之前运行所有“睡眠1”,“睡眠2”和“睡眠3”剩下的文件。

====编辑====

我使用“promisified”XMLHttpRequest和Promise.all()加载文件。 (http://www.html5rocks.com/en/tutorials/es6/promises/

最佳, 尼古拉斯

2 个答案:

答案 0 :(得分:0)

  

但我得不到的是为什么它会运行所有&#34;睡眠1&#34;,&#34;睡眠2&#34;并且&#34;睡3&#34;在继续下载剩余文件之前。

当有多个承诺等待解决时,Promise回调基本上以任意顺序 1 运行。在你的情况下,它只是选择运行sequence回调(不幸的是每个回调很长),然后回到你的ajax请求的onload回调来解决其他的承诺,之前运行他们的回调,继续下载剩余的文件。

解决方案非常简单:不要使用sleep,也不要使用长时间运行的代码(但要使其异步)。

1:当然,链中的回调(.then(A).then(B))需要按照承诺的顺序运行。
并且Promises / A +要求对同一个承诺的多个回调按注册顺序(p.then(A); p.then(B);)运行。
ECMAScript6要求多个已解析的Promises上的回调按照承诺解析的顺序运行。

答案 1 :(得分:0)

我认为你在这里问的是什么(这个可怕的忙等待睡眠()函数,没有人应该在实际代码中使用)是怎样的.then()函数优先于onload函数JS事件循环中的1}}事件?

他们这样做,这是因为promises在一个微任务队列上运行,该队列与主任务队列分开,并在后者之前排干。

另见this answer to another question