The*_*ies 6 javascript promise
只是学习承诺。JavaScript 是单线程的吗?那么当它使用 fetch api 发出 http 请求时,这一切都发生在一个线程中吗?
那么它如何管理 PromisePool 的并发呢?
var p = Promise(...)
p.then(
...//stuff1
)
p.then(
//stuff2
)
Run Code Online (Sandbox Code Playgroud)
那么上面的两个不能在多线程上运行,对吗?仅在一个线程中?谢谢
JavaScript 是单线程的吗?
不,这是一种常见的过度简化。
JavaScript 运行一个主事件循环,它一次只能做一件事。
一般来说,所有 JavaScript 都会在该事件循环上运行,因此一次只会运行一段 JS。
然而,许多 JavaScript 函数调用的代码不是 JavaScript。以fetch浏览器为例。发出 HTTP 请求的责任由浏览器在主事件循环之外负责,因此它可以发出多个请求并等待响应,同时 JS 程序继续运行其他任务。
Web Workers(浏览器)和 Worker Threads (Node.js) 是让您将 JS 代码移出主事件循环的工具。
这些可以使用线程来实现。
我有一些代码可以在文件系统中搜索音频文件,然后从中提取元数据。收集所有元数据后,会将其传递以进行进一步处理。
我当前的实现使用for循环,await以便一次只处理一个文件的元数据。
我的第一次尝试尝试并行执行它们,并尝试同时读取数百个音频文件,耗尽了系统上的所有 RAM。
例如,我可以切换到 Promise Pool 并一次读取 4 个文件(每个 CPU 核心 1 个),以获得两全其美的效果。
JavaScript 是单线程的吗?
是的,一段 JavaScript 代码总是在一个代理中运行,并且一个代理一次只能执行一个函数。
那么当它使用 fetch api 发出 http 请求时,这一切都发生在一个线程中吗?
不,不是真的。虽然您的 JavaScript 代码无法与其他 JavaScript 代码并行运行,但浏览器可以并行执行其他操作(例如渲染页面、垃圾收集等),包括为您执行请求。一旦响应返回,结果就会通过解析 Promise 将结果移回 JavaScript。
它如何管理并发?
虽然两个函数不能同时运行,但两个异步函数(或 Promise 链)可以同时运行,因为它们由多个执行单元组成,一旦其中一个完成,另一个就可以接管:
(async function first() {
await undefined;
console.log(2);
await undefined;
console.log(4);
})();
(async function second() {
console.log(1);
await undefined;
console.log(3);
})();
Run Code Online (Sandbox Code Playgroud)
因此 JavaScript 确实具有某种形式的并发性,但是是在函数级别(或异步函数中的块),而不是在单个指令级别。
为了获得真正的并行执行,您需要多个代理(WebWorkers、ServiceWorkers),然后它们还可以以有限的方式共享内存。