Promise你学会了吗

Promise

ES6新增的内置类,用来管理异步编程代码,避免回调地狱--->承诺者设计模式

+不兼容IE,如果需要兼容IE,则基于@babel/polyfill处理(原理是重写了Promise)

+基于new使用,例如:new Promise(...)

Ajax中的“串行”&“并行”:多个ajax请求的管理模式

+串行:一般是多个请求之间存在依赖(例如:当前请求需要用到上个请求获取的结果),此时我们只能等待上个请求成功,才能发送下一个请求。。。。

+并行:多个请求之间没有依赖,可以同时发送,谁先请求回来,先处理谁

//回调函数方式:基于定时器模拟出异步ajax请求效果

私有属性和方法

[[PromiseState]]: "pending" 实例的状态 pending:准备, fulfilled:成功, rejected:失败

一旦状态值从pending改为fulfilled或者rejected,则不能修改

[[PromiseResult]]: undefined 实例的值

Promise.prototype公共属性和方法

then

catch

finally

Symbol.toStringTA:"Promise"
===================================

基础语法: 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中,最后处理

p.catch([onrejected])===p.then(null,[onrejected])

.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{ }包起来



#js#
全部评论
学到了,感谢大佬的整理
点赞 回复 分享
发布于 2022-09-14 20:45 陕西

相关推荐

点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务