是 promise.all 有用的,因为 javascript 是在单个线程中执行的
Is promise.all useful given that javascript is executed in a single thread?
,在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 作为一种语言并没有说任何关于并发性的事情。事实上,在很多场景中,你可以在 Web、节点中以及自己在现有应用程序中集成 JS 引擎时创建和运行多线程 JavaScript - WebWorkers。
事实上,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!");
});
在这里,一次进行 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
});
它会发出一个请求,等待它完成,发出另一个请求,等待它,然后才发出第三个请求,然后才解决。
所以 - 第一种情况:
- 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 通常在多线程环境中执行。
在客户端
除了工作线程之外,每个 iframe、窗口选项卡或打开的窗口都有自己的线程,这些线程都与窗口消息传递 API 通信,或者如果没有跨源限制,你可以从中直接访问其文档属性。
一些 DOM/HTML5 API 提出了同步 API,W3C 的一些人正在努力使这些同步版本只能从 Web Worker 使用,可能只能从专用 Worker 使用。
在服务器端
如果 node.js 默认在单个线程中运行在 JavaScript 中,它仍然可以生成具有自己的线程的其他节点进程并与之通信。它实际上还提供了其API的一些同步版本。
大多数其他服务器JS平台,如Wakanda,RingoJS,TeaJS,APE,SilkJS等都是多线程的,可以与同步API同步运行JavaScript(Wakanda还允许在同步API或异步特定线程中轻松使用异步API)
- 在javaservlet doPost方法中启动线程时,无法返回异常消息
- javascript中的多线程
- Javascript支持多线程吗
- 如何在nodejs中创建线程池
- 起始节点.js用于并行的线程池
- Doppio:多线程是如何工作的,有什么限制吗
- 为什么Javascript SetTimeout()不是多线程的
- Selenium异步脚本在自己的线程中阻塞其他脚本
- Node.js如何使用更少的线程来处理多个连接
- Node.js如何用一个线程处理同时请求
- 从多线程C++插件回调NodeJS Javascript函数
- 电子框架是否允许网络工作者进行多线程处理
- 追加新web组件时出现线程问题
- 隔离每个线程/用户的setInterval
- Angular js显示类似gmail的重叠电子邮件线程
- 在节点.js的多个线程中运行任务
- firebug(1.10.1)建议javascript不局限于firefox(13.0)中的单个线程
- 对单个 PHP 脚本的多个 AJAX 调用划分工作负载 = 服务器端多线程
- 是 promise.all 有用的,因为 javascript 是在单个线程中执行的
- 浏览器脚本是否强制要求在单个线程上运行