javascript - 鉴于 javascript 在单线程中执行,promise.all 有用吗?

标签 javascript promise q

例如,在 kriskowal 的 Q 中,可以执行以下操作:

promise1.then(function(p1){
  var p2 = makePromise2();
  var p3 = makePromise3();
  var p4 = makePromise4();
  return [p2, p3, p4];
})
.all(promises, function(){
  console.log('all promises fulfilled');
}, function(reason){
  console.log('a promise was rejected: ' + reason.toString());
});

鉴于 javascript 在单个线程中执行,与简单地执行一系列 then() 调用相比,这是否有任何好处、性能或其他方面?

最佳答案

首先 - JavaScript 作为一门语言并没有说明并发性。事实上,在很多场景中,您可以创建和运行多线程 JavaScript - WebWorkers 在 Web 中、在节点中以及在自己将 JS 引擎集成到现有应用程序中时。

事实上,JavaScript 语言中没有任何异步(直到 ES2015)。然而,在实践中——JavaScript 与世界交互的宿主环境实现了异步 API。

虽然 JavaScript DOM 代码的执行是单线程的,但 I/O 操作实际上在不同的线程上运行,并且事件会通知 JavaScript 线程更改。有时,完全像 Windows 中的 IOCP(I/O 完成端口)那样使用操作系统工具来实现异步并发。

让我们以 AJAX 为例。假设我有一个 URL 列表,我将它们中的每一个映射到一个 XHR 调用。

// with all
var a = ["url1","url2","url3"].map(makeAjaxPromise); // make 3 ajax calls
Promise.all(a).spread(function(res1,res2,res3){ // Q.all with Q
     alert("Everything loaded!");
});

在这里,一次进行了 3 个 ajax 调用。即使在这种情况下 JavaScript 在单个线程中运行 - 请求都是并行发出的,一旦它们完成,线程就会使用“事件循环”通知代码,当事件完成时通知代码,这反过来又解决了 Promise。

但是,当你这样做
 makeAjaxPromise("url1").
 then(makeAjaxPromise.bind(null,"url2").
 then(makeAjaxPromise.bind(null,"url3").then(function(){
      alert("Everything loaded!"); // disregarding getting the data here
 });

它会发出一个请求,等待它完成,发出另一个请求,等待它,然后再发出第三个请求,然后才解决。

所以 - 第一种情况:
  • JavaScript 线程进行 3 次 DOM API 调用
  • DOM API 获取这些调用并发出 XHR 请求,它立即将控制权交还给 JavaScript
  • 当这些请求准备好时,它会通知 JavaScript 并运行处理程序(如果它有空的话)。

  • 第二种情况
  • JavaScript 线程进行 DOM API 调用。
  • DOM API 被调用,发出 XHR 请求,将控制权交还给 JavaScript。
  • 当第一个请求准备好时,JavaScript 会收到通知并运行下一个:
    -JavaScript 线程进行 DOM API 调用。
  • DOM API 被调用,发出 XHR 请求,将控制权交还给 JavaScript。
  • 当第二个请求准备好时,JavaScript 会收到通知并运行下一个:
    -JavaScript 线程进行 DOM API 调用。
  • DOM API 被调用,发出 XHR 请求,将控制权交还给 JavaScript。
  • 当第三个请求准备好时,JavaScript 会收到通知并运行下一行:
  • 三个都准备好了。

  • 所以在第二种情况下,请求不是并行发出的,JavaScript 必须等待更多时间,可能是三倍。

    关于javascript - 鉴于 javascript 在单线程中执行,promise.all 有用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22844441/

    相关文章:

    jquery - AngularJS Promise 不会检索深度包装的 jquery $.post 调用

    JavaScript 页面滚动位置

    javascript - gmap3 获取集群位置

    javascript - 将修改后的对象从 promise 返回到 async() block

    javascript - 如何将统一渐变应用于 (particule.js) Canvas ?

    javascript - 是否有一种纯粹的基于 Promise 的映射/连接集合的方法?

    javascript - Promise 内的异步调用

    javascript - 探索/浏览 promise 链

    javascript - 返回搜索 promise

    node.js - 如何将异步调用转换为 bluebird promise :