XHR OnLoad Promise 阻止其他 OnLoad 回调

XHR OnLoad Promise blocking other OnLoad callbacks

我正在尝试从我的服务器下载文件然后 运行 对加载数据的承诺。 我的问题是我的 Promise 似乎出于某种原因阻止了所有内容:

它开始下载所有文件,一旦下载了第一个文件,它就阻止其他文件下载,运行 它的 "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;
    }
  }
 }

在控制台中 returns:

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

如有任何帮助,我们将不胜感激。

我可以理解当 "sleep" 为 运行ning 时下载被阻止,但我不明白的是为什么它 运行 全部 "sleep 1" 、"sleep 2" 和 "sleep 3",然后继续下载其余文件。

==== 编辑 ====

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

最好的, 尼古拉斯

but what I do not get is why it runs all the "sleep 1", "sleep 2" and "sleep 3" before continuing to download the remaining files.

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

解决方案很简单:不要使用 sleep,也不要使用长 运行ning 代码(但要使其异步)。

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

我想你在这里问的(这个可怕的忙等待 sleep() 函数,任何人都不应该在实际代码中使用)是为什么所有 .then() 函数都优先于onload JS 事件循环中的事件?

他们这样做了,这是因为在微任务队列上承诺 运行,它与主任务队列分开,并在后者之前排空。

另见