并发是宏观概念,我分别有任务 A 和任务 B,在一段时间内通过任务间的切换完成了这两个任务,这种情况就可以称之为并发。
并行是微观概念,假设 CPU 中存在两个核心,那么我就可以同时完成任务 A、B。同时完成多个任务的情况就可以称之为并行。
回调地狱的根本问题就是:
嵌套函数存在耦合性,一旦有所改动,就会牵一发而动全身
嵌套函数一多,就很难处理错误
function *foo(x) {
let y = 2 * (yield (x + 1))
let z = yield (y / 3)
return (x + y + z)
}
let it = foo(5)
console.log(it.next())//next()第一次调用,返回第一个yield后面的值
VM229:7 {value: 6, done: false}
it.next(12)//next()第二次调用,入参赋值给第一个yield后面的值,返回当前yield后面的值
{value: 8, done: false}
it.next(13)//入参赋值给上一个yield后面的值,返回函数return值
{value: 42, done: true}
解析:z=13 x=5 y=24
Promise:承诺会在未来有一个确切的答复,一旦从等待状态变成为其他状态就永远不能更改状态
当我们在构造 Promise 的时候,构造函数内部的代码是立即执行的
new Promise((resolve, reject) => {
console.log('new Promise')
resolve('success')
})
console.log('finifsh')
// new Promise -> finifsh
Promise 缺点:比如无法取消 Promise,错误需要通过回调函数捕获。
async 及 await
一个函数如果加上 async ,那么该函数就会返回一个 Promise
async function test() {
return "1"
}
console.log(test()) // -> Promise {<resolved>: "1"}
async 就是将函数返回值使用 Promise.resolve() 包裹了下
相比 Promise 来说,优势:处理 then 的调用链,优雅地解决回调地狱问题。
缺点,因为 await 将异步代码改造成了同步代码,如果多个异步代码没有依赖性却使用了 await 会导致性能上的降低。
async function test() {
// 以下代码没有依赖性的话,完全可以使用 Promise.all 的方式
// 如果有依赖性的话,其实就是解决回调地狱的例子了
await fetch(url)
await fetch(url1)
await fetch(url2)
}