异步函数和毁掉函数是 JS 单线程并行模型的核心。
在 JS 中,需要区分 I/O 操作 和 CPU 密集型操作 。针对 I/O 来说,例如网络请求和文件操作,需要程序等待数据准备好后再进行下一步操作,与此同时,程序可以执行其他的代码,这并不会对程序产生阻塞。
而对于 CPU 密集型的操作来说,它会造成线程的阻塞。
- 对于 I/O 操作来说,我们需要使用
promise,events和callback来对请求做划分(schedule) - 对于 CPU 密集型的操作来说,它会不可避免的阻塞程序的执行,这时候可以使用
worker threads/web workers来执行
在使用 ascyn/await 的时候需要注意,未经处理的 promise 将会造成很大的内存使用。
注意事项
- 不要使用
return await语句
return await 的问题
通常在函数中, return 语句表明了函数的结束,并且会从当前调用栈中弹出。对于 async 函数来讲,会将一个值用一个已解决(resolved)的 promise 进行包裹,然后再进行返回。
与此同时, await 语句标明 async 函数暂停执行,直到一个给定的 promise 解决之后。将 return 和 await 进行结合之后会导致多余的对已经解决的 promise 进行多余的包装和解包装的操作。
通常来说,在 async 函数中最后的 promise 应该被直接返回。
async function saveJSON(output) {const response = await fetch('https://api.github.com')const json = await response.json()const text = JSON.stringify(json)return fs.readFile(output, text)}
避免对 async 函数的滥用:
import { promises as fs } from 'fs';// This is a not-so-efficient wrapper for the native file reader.async function readFile(filename) {const contents = await fs.readFile(filename, { encoding: 'utf8' });return contents;}// Preferred// This optimization avoids the `async` wrapper overhead.function readFile(filename) {return fs.readFile(filename, { encoding: 'utf8' });}
