promise.all有用,因为javascript是在一个线程中执行的吗?

bbl*_*ack 5 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());
});
Run Code Online (Sandbox Code Playgroud)

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

Ben*_*aum 17

首先,JavaScript作为一种语言并没有说明并发性.实际上,在很多场景中,您可以创建和运行多线程JavaScript - Web中的webWorkers,节点中以及自己在现有应用程序中集成JS引擎.

事实上,JavaScript语言中没有任何异步(直到ES2015).但是,实际上 - JavaScript与世界交互的主机环境实现了异步API.

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

我们以AJAX为例.假设我有一个URL列表,我将每个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!");
});
Run Code Online (Sandbox Code Playgroud)

在这里,3个ajax调用立即进行.即使JavaScript在这种情况下在单个线程中运行 - 请求都是并行完成的,并且线程在完成后会通过"事件循环"得到通知,该事件循环在事件完成时通知代码,这反过来解析了承诺.

但是,当你这样做的时候

 makeAjaxPromise("url1").
 then(makeAjaxPromise.bind(null,"url2").
 then(makeAjaxPromise.bind(null,"url3").then(function(){
      alert("Everything loaded!"); // disregarding getting the data here
 });
Run Code Online (Sandbox Code Playgroud)

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

所以 - 第一种情况:

  • 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必须等待更多,可能是等待的三倍.

  • 非常清楚.谢谢!关键是我对I/O操作的区别. (2认同)