ES6_Promise

基础概念

Web页面是单线程架构模型,决定了编写代码的形式为异步编程。Promise是ES6引入的异步编程的新解决方案(传统解决方案:回调函数+事件),通过回调任务的层层嵌套来保证异步任务的执行顺序,但是会出现回调地狱。
Promise是一个包含异步操作结果的对象。Promise解决的是异步编码风格的问题。
Promise对象有两个特点:

  • 对象的状态不受外界影响。有三种状态:pending、resolved、rejected。只有异步操作的结果可以决定是哪一种状态,任何其他操作无法改变这种状态。
  • 一旦状态改变,就不会再变,且任何时候都可以获得这个结果。pending→resolved,pending→rejected。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject,它们也是两个函数,由 JavaScript 引擎提供,不用自己部署。let p=new Promise((resolve,reject)=>{})
resolve:pending→resolved,将异步操作的结果作为参数传递出去;
reject:pending→rejected,将异步操作的错误作为参数传递出去。
一个例子:

        const imgurl='11.webp';
        const imgPromise=function(url){
            return new Promise((resolve,reject)=>{
                const img=new Image();
                img.src=url;
                img.onload=()=>resolve(
                    img
                );
                img.onerror=()=>reject(
                    new Error('出错了')
                )
            })
        }
        imgPromise(imgurl).then(img=>
            {document.body.appendChild(img)}
        ).catch((error)=>{document.body.innerHTML=error})

方法:

then方法的作用是:为Promise实例添加状态改变时的回调函数,接收两个回调作为参数:状态变为resolved时的回调和状态变为rejected时的回调
then的参数:回调函数的返回值:
1,返回Promise实例对象,返回的该实例对象会调用下一个then
2,返回普通值,直接传递给下一个then,通过then参数中函数的参数接受该值。这种情况下then会默认产生一个Promise实例对象。
catch:一般来说,不要在then()方法里面定义 Reject 状态的回调函数,总是使用catch方法:

 p.then(function(value){
     //success
 })
 .catch(function(error){
     //failure
 }).finally(function(){
});

finally:指定不管最后状态如何都会执行的回调函数

Promise.all()并发处理多个异步任务,所有任务都执行完成才能得到结果;
Promise.race()并发处理多个异步任务,只要有一个任务完后就能得到结果。

then和catch都属于实例方法,通过实例调用(定义在Promise原型链上),all和race是两个对象方法,直接通过Promise对象调用。

一些问题

为什么需要Promise有了Promise对象,可以将异步操作以同步操作的流程表达出来,避免了回调地狱。
Promise——消灭嵌套调用错误合并处理
Promise 是怎么消灭嵌套回调的
产生嵌套函数的一个主要原因是在发起任务请求时会带上回调函数,这样当任务处理结束之后,下个任务就只能在回调函数中来处理了。Promise 主要通过下面两步解决循环嵌套回调问题的。首先,Promise 实现了回调函数的延时绑定。

let x1=new Promise(executor);
let x2=x1.then(onResolve);//onResolve这个回调函数延迟绑定,执行到then时才会调用onResolve

其次,需要将回调函数 onResolve 的返回值穿透到最外层。
Promise 中是如何实现回调函数返回值穿透的?
首先Promise的执行结果保存在promise的data变量中,然后是.then方法返回值为使用resolved或rejected回调方法新建的一个promise对象,即例如成功则返回new Promise(resolved),将前一个promise的data值赋给新建的promise
Promise 是怎么错误合并处理的
之所以可以使用最后一个对象来捕获所有异常,是因为 Promise 对象的错误具有“冒泡”性质,会一直向后传递,直到被 onReject 函数处理或 catch 语句捕获为止。具备了这样“冒泡”的特性后,就不需要在每个 Promise 对象中单独捕获异常了。
Promise 出错后,是怎么通过“冒泡”传递给最后那个捕获异常的函数
promise内部有resolved_和rejected_变量保存成功和失败的回调,进入.then(resolved,rejected)时会判断rejected参数是否为函数,若是函数,错误时使用rejected处理错误;若不是,则错误时直接throw错误,一直传递到最后的捕获,若最后没有被捕获,则会报错。可通过监听unhandledrejection事件捕获未处理的promise错误。
Promise 中为什么要引入微任务
由于promise采用.then延时绑定回调机制,而new Promise时又需要直接执行promise中的方法,即发生了先执行方法后添加回调的过程,此时需等待then方法绑定两个回调后才能继续执行方法回调,便可将回调添加到当前js调用栈中执行结束后的任务队列中,由于宏任务较多容易堵塞,则采用了微任务,保证了实时性和效率。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值