res*_*sle 17 javascript web-worker async-await
线程化,Web工作者和声明的函数之间的区别是什么
async function xxx()
{
}
Run Code Online (Sandbox Code Playgroud)
?
我知道web worker是在不同的线程上执行的,但异步函数呢?这些函数的线程是否与通过setInterval执行的函数相同,或者它们是否受到另一种不同类型的线程的影响?
Jon*_*lms 10
异步函数只是Promises的合成糖,它们是回调的包装器.所以基本上当你等待 js引擎继续其他东西时,直到你正在等待回调的回调.是否涉及另一个线程取决于您在异步函数中等待的内容.如果它是一个timer(Async),则设置一个内部定时器,js线程继续执行其他操作,直到定时器完成,然后继续执行.这种行为与采取回调或返回承诺的每个函数有些相同.但是其中一些,特别是在nodejs环境(Promises,Callbacks)中将在内部启动另一个线程.您只需移交一些参数并在线程完成时接收结果.但是,对于webworkers,您可以直接控制另一个线程.对于shure,你也可以等待来自其他线程的动作:
const workerDone = new Promise(res => window.onmessage = res);
(async function(){
const result = await workerDone;
//...
})();
Run Code Online (Sandbox Code Playgroud)
TLDR:
JS <---> callbacks / promises <--> internal Thread / Webworker
Run Code Online (Sandbox Code Playgroud)
与WebWorkers相比,WebWorkers函数永远不能保证在单独的线程上执行.
他们只是在他们的响应到来之前不会阻止整个线程.你可以认为它们被注册为等待结果,让其他代码执行,当它们的响应通过时它们被执行; 因此名称异步编程.
这是通过消息队列实现的,消息队列是要处理的消息列表.每条消息都有一个相关的函数,可以调用它来处理消息.
这样做:
setTimeout(() => {
console.log('foo')
}, 1000)
Run Code Online (Sandbox Code Playgroud)
只需将回调函数(记录到控制台)添加到消息队列中.当1000ms计时器过去时,消息将从消息队列中弹出并执行.
当计时器正在滴答作响时,其他代码可以自由执行.这就是多线程的假象.
async上面的示例使用回调.setTimeout并且Promises在较低级别以相同的方式工作 - 它们依赖于该消息队列概念 - 但只是在语法上不同.
工人也可以通过异步代码(即Promises)进行访问,但是,工人是解决CPU密集型任务的一种解决方案,这些任务会阻塞正在运行JS代码的线程。即使此CPU密集型功能是异步调用的。
因此,如果您有喜欢的CPU密集型功能,renderThread(duration)并且喜欢
new Promise((v,x) => setTimeout(_ => (renderThread(500), v(1)),0)
.then(v => console.log(v);
new Promise((v,x) => setTimeout(_ => (renderThread(100), v(2)),0)
.then(v => console.log(v);
Run Code Online (Sandbox Code Playgroud)
即使第二个完成花费的时间较少,也只有在第一个释放CPU线程之后才调用它。因此,我们将首先得到1,然后2在控制台上。
但是对不同的工人这两个功能一直运行,那么我们预计结果将是2和1作为然后他们可以同时运行,第二个完成并返回的消息早。
因此,对于基本的IO操作而言,标准的单线程异步代码非常有效,并且对Worker的需求源于对CPU密集型任务的需求,这些任务可以进行分段(一次分配给多个Worker),例如FFT等。
异步函数与Web worker或节点子进程无关 - 与那些不同,它们不是多线程并行处理的解决方案.
一个async function是刚刚1返回一个承诺函数语法糖then()链.
async function example() {
await delay(1000);
console.log("waited.");
}
Run Code Online (Sandbox Code Playgroud)
就像是一样的
function example() {
return Promise.resolve(delay(1000)).then(() => {
console.log("waited.");
});
}
Run Code Online (Sandbox Code Playgroud)
这两个人的行为几乎无法区分.根据await承诺的语义或指定的语义,并且每一个async function确实都会对其结果作出承诺.
1:句法糖得到一个位在控制结构,例如存在更复杂if/ else或它们更难表达为线性承诺链环,但它仍然是概念上是相同.
这些函数的线程是否与执行的函数相同
setInterval?
是的,async functions 的异步部分在标准事件循环上作为(promise)回调运行.在delay上面的例子将实现与正常setTimeout-包裹在便于消费一个承诺:
function delay(t) {
return new Promise(resolve => {
setTimeout(resolve, t);
});
}
Run Code Online (Sandbox Code Playgroud)
我想根据我通过所有其他人的答案收集到的理解,对我的问题添加我自己的答案:
最终,除了网络工作者之外,所有人都是被美化的回调。异步函数中的代码、通过 Promise 调用的函数、通过 setInterval 调用的函数等 - 全部都在主线程中执行,使用类似于上下文切换的机制。根本不存在并行性。
真正的并行执行及其所有优点和缺陷,只适用于网络工作者和网络工作者。
(遗憾 - 我认为通过“异步函数”,我们终于得到了简化和“内联”线程)
| 归档时间: |
|
| 查看次数: |
2755 次 |
| 最近记录: |