Promise你学会了吗
Promise
ES6新增的内置类,用来管理异步编程代码,避免回调地狱--->承诺者设计模式
+不兼容IE,如果需要兼容IE,则基于@babel/polyfill处理(原理是重写了Promise)
+基于new使用,例如:new Promise(...)
Ajax中的“串行”&“并行”:多个ajax请求的管理模式
+串行:一般是多个请求之间存在依赖(例如:当前请求需要用到上个请求获取的结果),此时我们只能等待上个请求成功,才能发送下一个请求。。。。
+并行:多个请求之间没有依赖,可以同时发送,谁先请求回来,先处理谁
私有属性和方法
[[PromiseState]]: "pending" 实例的状态 pending:准备, fulfilled:成功, rejected:失败
一旦状态值从pending改为fulfilled或者rejected,则不能修改
[[PromiseResult]]: undefined 实例的值
Promise.prototype公共属性和方法
then
catch
finally
基础语法: let p=new Promise([executor]);
[executor]必须传,而且是传递一个函数,否则会报错
[executor]函数执行是同步的:在“new Promise”的时候,会把函数立即执行
promise内部在执行函数的时候,还会给函数传递实参值,我们基于resolve,reject,形参变量来获取这个值
resolve,reject存储的值是一个小函数,后期把相关的函数执行,会修改实例的状态和值
=================================实例对象的研究
promise实例.then([onfulfilled],[onrejected])
根据实例的状态,决定执行哪一个函数
+如果实例状态是pending,则两个函数暂时都不执行
+如果状态是成功fulfilled,则执行[onfulfilled]
+如果状态是失败rejected,则执行[onrejected]
把实例的值传递给相关的函数,所以value、reason获取的就是当前实例的值
同一个实例可以多次调用then方法,虽然这种操作很少见,这样在知道实例状态之后,会把每一次then中传递的函数都触发执行
========================
@1创建promise实例的第一种方案:new Promise((resolve,reject)=>{...})
实例的状态和值如何被修改
+基于resolve、reject执行,可以修改实例的状态和值
+executor函数执行报错
@2创建实例的第二种方案:Promise.resolve/reject
Promise.resolve创建一个状态是成功fulfilled,值是100的实例
Promise.reject(0)创建一个状态是失败rejected,值是0的实例
@3创建实例的第三种方案:let p2=p1.then([onfuifilled],[onrejected])
每次执行THEN方法,p1的状态会决定onfulfilled和onrejected谁先执行,也会创建一个全新的promise实例p2
如何修改p2的状态和值
总则:无论是onfulfilled还是onrejected执行,函数执行的一些细节决定了新实例p2的状态和值
@1函数执行是否报错,如果报错,则p2是rejected,值是报错原因;
如果没报错,再看函数执行的返回值,
如果返回值是另外一个promise实例(名称other),则“other”的状态和值决定了p2的状态和值
如果不是promise实例,则p2状态是成功,值是函数的返回值
如果没有写返回值,则p2状态是成功,值是undefined
这种机制可以保证一直.then下去,我们把其称之为then链机制
THEN具备“穿透、顺延”性
onfulfilled或者onrejected可以不传递
p.then(onfulfilled)
p.then(null,onrejected)
如果不传递,则顺延至下一个同等状态和方法上
原理:我们不设置onfulfilled还是onrejected,在promise内部会帮我们设置默认值
默认加的函数,可以保证状态和值的顺延
=========================================//真实项目中,一般then只传递onfulfilled,在最末尾设置》catch(也就是onrejected)
好处:then中只处理状态成功要做的事情,不论在何时遇到失败的实例,都会顺延至末尾catch中,最后处理
.finally(()=>{
//不论实例状态成功还是失败,最后都要执行这里{一般不用}
})
@4创建Promise实例的第四种方案:Promise.all/any/race
let p=Promise.all();
//方法返回值是一个新的promise实例
//[promise]:包含多个promise实例的集合
//检测集合中每一个实例的状态
//只要有一个实例是失败态,则p是失败的,值是当前这一项失败的原因
//所有项都成功,则p的状态是成功,它的值也是一个数组集合,按照原有【promise】的顺序,依次存储每一项成功的结果
// 如果集合中有一项不是promise的实例,则每部会把其变为状态为成功,值是本身的实例
//Promise.any:[promise]集合中有一项成功,则p就是成功的(值就是成功的这一项),所有项都失败,p才是失败的(不是ES6中新增的,是ES11中新增的,所以浏览器的版本如果低一些,也是不兼容的)
//Promise.race:谁快则以谁为准,不论成功还是失败
=========================================
promise是基于承诺者设计模式,来管理异步编程代码的
//executor函数中来管理异步代码,当异步操作结束,基于resolve,reject修改实例状态,从而决定then传递的函数该执行哪一个
基于回调函数方式管理异步操作(都是异步结束后干点啥事),很容易导致回调地狱
============================================
async/await:Promise+Generator的语法糖,让promise的语法使用起来更简洁(ES8新增的)
async:用来修饰一个函数,目的是让函数返回一个promise实例
返回实例的状态是成功还是失败,取决于函数执行的细节
函数执行报错,则返回失败的实例(值是报错原因)
函数执行的返回值不是promise的实例,则返回的状态是成功,值是返回值promise的实例
async最主要作用是:我们如果想在函数中使用await,则当前函数必须经过async来修饰
await:可以等待异步操作结束,返回promise实例的状态的成功,再去执行当前上下文“下面的代码”(await只能用在函数中)
let value =await[promise实例]
+await 后面要跟一个promise实例
await 10如果不是实例,则默认转换状态为成功,值是本身的实例——---------->await Promise.resolve(10)
await func();先把函数执行,把返回值作为一个promise实例去监测
等待promise状态是成功,把成功的值赋值给value,当前上下文中,下面的代码才会继续执行
如果实例是是失败的,则下面的代码不会再执行,也不会给value赋值
如何处理await后的promise实例为失败的情况
用try { }catch{ }包起来
顺丰集团工作强度 406人发布