Javascript异步功能和Web Worker之间的区别? [英] Difference between Javascript async functions and Web workers?

查看:371
本文介绍了Javascript异步功能和Web Worker之间的区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从线程角度看,Web Worker和声明为

Threading-wise, what's the difference between web workers and functions declared as

async function xxx()
{
}

?

我知道Web Worker是在单独的线程上执行的,但是异步函数呢?这样的函数是否以与通过setInterval执行的函数相同的方式进行线程化,或者它们还要经受另一种不同类型的线程化?

I am aware web workers are executed on separate threads, but what about async functions? Are such functions threaded in the same way as a function executed through setInterval is, or are they subject to yet another different kind of threading?

推荐答案

async函数只是语法糖 答应,它们是回调的包装器.

async functions are just syntactic sugar around Promises and they are wrappers for callbacks.

// v await is just syntactic sugar
//                 v Promises are just wrappers
//                                         v functions taking callbacks are actually the source for the asynchronous behavior
   await new Promise(resolve => setTimeout(resolve));

现在,代码可以立即回调回调,例如如果您.filter一个数组,或者引擎可以将回调内部存储在某个地方.然后,当特定的 event 发生时,它将执行回调.可以说这些是异步回调,通常是我们包装到Promises中的内容,然后await.

Now a callback could be called back immediately by the code, e.g. if you .filter an array, or the engine could store the callback internally somewhere. Then, when a specific event occurs, it executes the callback. One could say that these are asynchronous callbacks, and those are usually the ones we wrap into Promises and await them.

为确保两个回调不会在同一时间运行(这会使并发修改成为可能,这会造成很多麻烦),只要事件发生,事件就不会立即得到处理,而是 task (带有参数的回调)被放入任务队列.每当JavaScript agent (=线程)完成当前任务的执行时,它就会在该队列中寻找下一个要处理的任务¹.

To make sure that two callbacks do not run at the same time (which would make concurrent modifications possible, which causes a lot of trouble) whenever an event occurs the event does not get processed immediately, instead a task (callback with arguments) gets placed into a task queue. Whenever the JavaScript agent (= thread) finishes execution of the current task, it looks into that queue for the next task to process¹.

因此,可以说async function只是表达一系列连续任务的一种方式.

Therefore one could say that an async function is just a way to express a continuous series of tasks.

 async function getPage() {
   // the first task starts fetching the webpage
   const response = await fetch("https://stackoverflow.com"); // callback gets registered under the hood somewhere, somewhen an event gets triggered
   // the second task starts parsing the content
   const result = await response.json(); // again, callback and event under the hood
   // the third task logs the result
   console.log(result);
}

// the same series of tasks can also be found here:
fetch("https://stackoverflow.com") // first task
   .then(response => response.json()) // second task / callback
   .then(result => console.log(result)); // third task / callback

尽管两个任务不能在一个代理(=线程)上并行运行,但是一个异步功能的任务可能在另一个代理的任务之间运行.因此,两个异步函数可以同时运行 .

Although two tasks cannot run in parallel on one agent (= thread), the task of one async function might run between the tasks of another. Therefore, two async functions can run concurrently.

现在谁会产生这些异步事件?这取决于您在async函数中正在等待的内容(或者:您注册的回调).如果它是一个计时器(setTimeout),则将设置一个内部计时器,并且JS线程将继续执行其他任务,直到完成该计时器为止,然后它执行传递的回调.其中一些线程,尤其是在Node.js环境(fetchfs.readFile)中,将在内部内部启动另一个线程.您只需交出一些参数,并在线程完成时(通过事件)接收结果.

Now who does produce these asynchronous events? That depends on what you are awaiting in the async function (or rather: what callback you registered). If it is a timer (setTimeout), an internal timer is set and the JS-thread continues with other tasks until the timer is done and then it executes the callback passed. Some of them, especially in the Node.js environment (fetch, fs.readFile) will start another thread internally. You only hand over some arguments and receive the results when the thread is done (through an event).

要获得真正的并行性,即同时运行两个任务,需要多个代理. WebWorkers恰恰是-代理商.因此,WebWorker中的代码独立运行(具有自己的任务队列和执行程序).

To get real parallelism, that is running two tasks at the same time, multiple agents are needed. WebWorkers are exactly that - agents. The code in the WebWorker therefore runs independently (has it's own task queues and executor).

代理可以通过事件相互通信,您可以使用回调对这些事件做出反应.当然,如果您将回调包装到Promises中,您也可以await从另一个代理执行操作:

Agents can communicate with each other via events, and you can react to those events with callbacks. For sure you can await actions from another agent too, if you wrap the callbacks into Promises:

const workerDone = new Promise(res => window.onmessage = res);

(async function(){
    const result = await workerDone;
        //...
})();

TL; DR:

JS  <---> callbacks / promises <--> internal Thread / Webworker


¹为此行为还创造了其他术语,例如事件循环/队列等.任务任务由ECMA262指定.


¹ There are other terms coined for this behavior, such as event loop / queue and others. The term task is specified by ECMA262.

这篇关于Javascript异步功能和Web Worker之间的区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆