深入浅出搞懂一下promise

  1. 最好理解的Promise教程 b站课程 --done
  2. 微信订阅号 promise --done
  3. 笔记promise 15题 理解 + 做练习 --done
  4. vue项目里的promise + 接口请求封装
  5. promise相关面试题梳理
  6. async、await

注意

想要实现一个 Promise,必须要遵循如下规则:

  • Promise 是一个提供符合标准的 then () 方法的对象。
  • 初始状态是 pending,能够转换成 fulfilled 或 rejected 状态。
  • 一旦 fulfilled 或 rejected 状态确定,再也不能转换成其他状态。
  • 一旦状态确定,必须要返回一个值,并且这个值是不可修改的。

原理

Promise 的运转实际上是一个观察者模式,then() 中的匿名函数充当观察者,Promise 实例充当被观察者。

管理多个 Promise 实例

Promise.all() / Promise.race() 可以将多个 Promise 实例包装成一个 Promise 实例,在处理并行的、没有依赖关系的请求时,能够节约大量的时间。

 function wait(ms) {
   return new Promise(resolve => setTimeout(resolve.bind(null, ms), ms))
 }

 // Promise.all
 Promise.all([wait(2000), wait(4000), wait(3000)])
   .then(console.log)
 // 4 秒后 [ 2000, 4000, 3000 ]

 // Promise.race
 Promise.race([wait(2000), wait(4000), wait(3000)])
   .then(console.log)
 // 2 秒后 2000

Promise 和 async&await
async&await 实际上只是建立在 Promise 之上的语法糖,让异步代码看上去更像同步代码,所以 async&await 在 JavaScript 线程中是非阻塞的,但在当前函数作用域内具备阻塞性质

使用 async&await 的优势

1. 简洁干净

写更少的代码,不需要特地创建一个匿名函数,放入 then() 方法中等待一个响应。

2. 处理条件语句

当一个异步返回值是另一段逻辑的判断条件,链式调用将随着层级的叠加变得更加复杂,很容易让人混淆。使用 async&await 将使代码可读性变得更好。

3. 处理中间值

异步函数常常存在一些异步返回值,作用仅限于成为下一段逻辑的入场券,如果经历层层链式调用,很容易成为另一种形式的 “回调地狱”。

4. Promise.all

对于多个异步返回中间值,搭配 Promise.all 使用能够提升逻辑性和性能。

 // async / await & Promise.all
 async function foo() {
   // ...
   const [a, b, c] = await Promise.all([promiseFnA(), promiseFnB(), promiseFnC()])
   const d = await promiseFnD()
   // ...
 }

错误处理

catch(rejectionFn) 其实就是 then(null, rejectionFn) 的别名。

取消一个 Promise

  1. 想结束一个 Promise 只能通过 resolve 或 reject 来改变其状态
  2. 或者利用 Promise.race() 的机制来同时注入一个会超时的异步函数(但是 Promise.race() 结束后主程序其实还在 pending 中,占用的资源并没有释放)
  3. Promise.race([anAsyncFn(), timeout(5000)])

总结

  1. 每当要使用异步代码时,请考虑使用 Promise。
  2. Promise 中所有方法的返回类型都是 Promise。
  3. Promise 中的状态改变是一次性的,建议在 reject() 方法中传递 Error 对象。
  4. 尽量为所有的 Promise 添加 then() 和 catch() 方法。
  5. 使用 Promise.all() 去运行多个 Promise。
  6. 倘若想在 then() 或 catch() 后都做点什么,可使用 finally()。
  7. 可以将多个 then() 挂载在同一个 Promise 上。
  8. async (异步)函数返回一个 Promise,所有返回 Promise 的函数也可以被视作一个异步函数。
  9. await 用于调用异步函数,直到其状态改变(fulfilled or rejected)。
  10. 使用 async /await 时要考虑上下文的依赖性,避免造成不必要的阻塞。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容