3 回答
TA贡献1798条经验 获得超7个赞
是在用
async
粗人await
的线吗?
一点都不。它只是使用 promises 的语法糖(真的非常有用的糖),而这又只是一种(真的非常有用的)使用回调的形式化方式。它很有用,因为您可以异步等待(不阻塞 JavaScript 主线程)本质上是异步的事物(如 HTTP 请求)。
如果您需要使用线程,请使用web workers、Node.js worker threads或您的环境提供的任何多线程。根据规范(现在),一次只允许一个线程在给定的 JavaScript“领域”(非常松散:您的代码运行的全局环境及其关联的对象等)中工作,因此只有一个线程一次可以访问该领域内的变量等,但线程可以通过消息传递(包括在它们之间传输对象而不制作副本)和共享内存进行协作。
例如:
async function isThisLikeTwoThreads() {
const a = slowFunction();
const b = fastFunction();
console.log(await a, await b);
}
isThisLikeTwoThreads
以下是调用时代码的作用:
slowFunction
被同步调用并将其返回值分配给a
.fastFunction
被同步调用并将其返回值分配给b
.当
isThisLikeTwoThreads
到达时await a
,它包装a
在一个承诺中(就像你做的那样Promise.resolve(a)
)并返回一个新的承诺(不是同一个)。让我们调用围绕a
“aPromise
”的承诺和函数“functionPromise
”返回的承诺。稍后
aPromise
结算时,如果被拒绝functionPromise
,则以相同的拒绝原因拒绝,并跳过以下步骤;如果满足,则下一步完成中的代码
isThisLikeTwoThreads
继续包装b
在 promise (bPromise
) 中并等待其解决结算时
bPromise
,如果被拒绝functionPromise
则以同样的拒绝原因被拒绝;如果已实现,则中的代码isThisLikeTwoThreads
会继续记录实现值aPromise
,bPromise
然后functionPromise
用该值实现undefined
上面的所有工作都是在完成调用的 JavaScript 线程上isThisLikeTwoThreads
完成的,但它分布在多个“作业”(JavaScript 术语;HTML 规范称它们为“任务”,并详细说明了它们如何进行'在浏览器上处理)。如果slowFunction
或fastFunction
启动了一个异步进程并为此返回了一个承诺,那么当 JavaScript 线程正在做其他事情时,该异步进程(例如,浏览器执行的 HTTP 调用)可能会继续与 JavaScript 线程并行,或者(如果它也在主线程上的 JavaScript 代码)可能已经竞争 JavaScript 线程上的其他工作(通过将作业添加到作业队列和线程在循环中处理它们来竞争)。
但是使用 promises 不会添加线程。:-)
TA贡献1811条经验 获得超6个赞
我建议您阅读本文以了解答案是否定的:https ://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop
总而言之,运行时使用多个线程进行内部操作(网络、磁盘...用于 Node.js 环境、渲染、indexedDB、网络...用于浏览器环境)但是您编写的 JavaScript 代码和您从中导入的代码不同的库将始终在单个线程中执行。异步操作会触发回调,回调会一个一个排队执行。
基本上执行此功能时会发生什么:
async function isThisLikeTwoThreads() {
const a = slowFunction();
const b = fastFunction();
console.log(await a, await b);
}
执行slowFunction。执行fastFunction。当promise 和promise 已解决时,将其余代码 ( console.log(await a, await b))入队。在返回后以及可能的排队回调返回后,在同一线程中运行。假设和都返回承诺,这相当于:abconsole.log isThisLikeTwoThreadsslowFunctionfastFunction
function isThisLikeTwoThreads() {
const a = slowFunction();
const b = fastFunction();
a.then(aResult => b.then(bResult => console.log(aResult, bResult)));
}
TA贡献2039条经验 获得超7个赞
相似但不相同。Javascript 一次只会做“一件事”。它基本上是单线程的。也就是说,它可能看起来很奇怪,因为结果可能似乎以不同的顺序到达 - 异步和等待等功能加剧了这种情况。
例如,即使您以 70fps 的速度渲染后台进程,在可用于完成承诺或接收事件通知的渲染逻辑中也存在小间隙——正是在这些时刻,承诺完成,给人以多线程的错觉。
如果你真的想锁定浏览器,试试这个:
let a = 1;
while (a == 1){
console.log("doing a thing");
}
你永远不会让 javascript 再次工作,而 chrome 或任何会扼杀你的脚本的东西。原因是当它进入该循环时——没有任何东西会再次接触它,不会呈现任何事件,也不会传递任何承诺——因此,单线程。
如果这是一个真正的多线程环境,您可以通过将变量更改为新值来从外部打破该循环。
添加回答
举报