博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【个人向整理】Promise
阅读量:6942 次
发布时间:2019-06-27

本文共 3003 字,大约阅读时间需要 10 分钟。

前言

网上关于Promise的文章确实是非常多了,但是自己实践的并不多,这里是针对自己的一个知识点小结和梳理,当然啦如果有错误欢迎提出^_^。

初定义

定义:Promise对象用于一个异步操作的最终完成/失败及其结果值的表示。

使用原因:避免回调嵌套层次过多。
拥有状态:

  • pending:初始/未定状态,初始化Promise时,调用executor函数后的状态。
  • fulfilled:成功状态。
  • rejected:失败状态。

状态转化:

  • pending -> fulfilled:操作成功
  • pending -> rejected:操作失败

状态转化是单向的,不可逆转。

最基本用法:

可以看到创建一个Promise实例,传入的参数是一个函数,这个函数称为executor/执行器。

new Promise((resolve, reject) => {    if (success) {        resolve(a) // pending to resolved    } else {        reject(err) // pending to rejectd    }})

方法

而Promise对象本身,有一些方法:

图片描述

  • race()
  • reject()
  • resolve()
  • all()

查看Promise的原型,发现它内置有几个方法:

图片描述

  • catch()
  • finally()
  • then()

Promise.prototype.then()

  • 参数:处理成功的函数,处理错误的函数
  • 返回值:返回一个Promise对象,所以可以链式调用。
promise.then(    () => { console.log('我是成功后被执行的') },    () => { console.log('我是失败后被执行的') })

Promise.prototype.catch()

  • 参数:捕捉的错误/reject()传来的参数
  • 返回值:返回一个Promise对象,所以可以链式调用。
  • Promise和then()中抛出错误能够不断传递,就能够在下一个catch()中统一处理,所以一般省略then中的第二个失败执行的函数。
promise.then(    () => { console.log('我是成功后被执行的') }).catch(    (err) => { console.log(err) })
使用rejects()方法改变状态和抛出错误 throw new Error() 的作用是相同的

Promise.all()

  • 参数:可迭代参数,如:数组。
  • 用途:处理一些并发的异步操作,需要保证每个都执行完毕。
  • 结果:状态全为fulfilled->fulfilled,否则->rejected。

Promise.race()

  • 参数:可迭代参数,如:数组。
  • 用途:处理一些并发的异步操作,只需要其中一个执行完毕。
  • 结果:所有异步操作中有一个状态先改变,就采纳那个最先改变的状态为结果。

Promise.resolve()

  • 参数:普通值、Promise对象、带有then的对象。
  • 结果:一般情况返回一个状态为fulfilled的Promise对象。解析发生错误则返回rejected的Promise对象。
Promise.resolve('success')// 其中[[PromiseStatus]]:"resolved"Promise.reject('fail') // 其中[[PromiseStatus]]:"rejected"Promise.resolve(Promise.reject('fail'))// 其中[[PromiseStatus]]:"rejected"

由这个例子可以看出浏览器认为resolvedfulfilled是等价的,但Promise.resolve() 不一定让promise最终是fulfilled。所以对于resolved本身和fulfilled的区别,可以理解为resolved等价于compiled,即可能是成功也可能是失败。

Promise.reject()

  • 参数: 发生异常的原因。
  • 结果:返回一个rejected状态的Promise对象。

注意点

状态变化

  • Promise状态只会改变一次。
  • 构造函数中的resolve()/reject()只有第一次执行有效,多次调用没有作用。
  • Promise状态改变,并且传递了一个值,后续调用.then()/.catch()都可直接拿到该值。

参数/返回值

  • .then()/.catch()的参数应该是函数,传入非函数则会发生值穿透。
Promise.resolve(1)  .then(2)  .then(Promise.resolve(3))  .then(console.log)  //1
  • .then()/.catch()不能返回Promise本身,会造成死循环。
  • .then()/.catch()中return一个error对象并不会抛出错误,所以无法捕捉。
因为返回任意一个非Promise 的值都会被包裹成Promise对象,即 return new Error('error!!!')等价于return Promise.resolve(new Error('error!!!'))

执行顺序

  • Promise构造函数是同步执行的,resolve()/reject()后的代码也会执行。Promise.then()中的函数是异步执行的。**

以下输出:1243

const promise = new Promise((resolve, reject) => {  console.log(1)  resolve()  console.log(2)})promise.then(() => {  console.log(3)})console.log(4)
  • process.nextTickpromise.then属于microtasksetImmediate属于 macrotask。在每一次事件循环中,macrotask只会提取一个执行,而microtask会一直提取,直到microsoft队列为空为止。

以下输出:end nextTick then setTimeout1 setTimeout2

process.nextTick(() => {  console.log('nextTick')})setTimeout(() => {  console.log('setTimeout1')})Promise.resolve()  .then(() => {    console.log('then')  })  setTimeout(() => {  console.log('setTimeout2')})console.log('end')

补充:

macrotasks:

  • setTimeout
  • setInterval
  • setImmediate
  • requestAnimationFrame
  • I/O
  • UI rendering

microtasks:

  • process.nextTick
  • Promises
  • Object.observe
  • MutationObserver

参考文章

转载地址:http://peanl.baihongyu.com/

你可能感兴趣的文章
VMware网络连接失败
查看>>
师兄的悔恨史
查看>>
Ubuntu14.04下SP_Flash_Tool_exe_Linux无法烧录
查看>>
hdu 5437 Alisha’s Party 优先队列
查看>>
【PHP】PHP获得第一章
查看>>
nslookup
查看>>
java05
查看>>
Android UI ActionBar功能-在 Action Bar 上添加按钮
查看>>
每天一个linux命令(10):cat 命令
查看>>
android ScrollView中嵌套listview listview可点击处理,可展开
查看>>
感谢dudu和他的博客园团队
查看>>
一个由proguard与fastJson引起的血案(转)
查看>>
clearing & settlement
查看>>
Lingo 做线性规划 - DEA
查看>>
Axure 全局辅助线(转)
查看>>
Delphi 7下使用VT实现树型列表结合控件
查看>>
【LINUX】——如何配置宿主机和虚拟机IP在同一网段
查看>>
工作介绍xml书包文件
查看>>
POJ 3450 Corporate Identity KMP解决问题的方法
查看>>
js原生设计模式——9外观模式封装2(小型代码库YJ)
查看>>