异步处理--Promise

异步处理–Promise

事件循环

浏览器事件循环和node事件循环

事件和回调函数

事件:某个对象的属性是一个函数,当发生某一件事时,运行该函数

dom.onclick = function(){

}

回调:运行某个函数以实现某个功能的时候,传入一个函数作为参数,当发生某件事的时候,会运行该函数。

dom.addEventListener("click", function(){

})

该模式主要面临以下两个问题:

  1. 回调地狱:某个异步操作需要等待之前的异步操作完成,无论用回调还是事件,都会陷入不断的嵌套
  2. 异步之间的联系:某个异步操作要等待多个异步操作的结果,对这种联系的处理,会让代码的复杂度剧增

异步处理通用模型

ES6参考大量异步场景,总结出一套通用的异步模型,并基于该模型推出了一个全新的API–Promise

  1. ES6 将某一件可能发生异步操作的事情,分为两个阶段:unsettledsettled

    unsettled: 未决阶段,表示事情还在进行前期的处理,并没有发生通向结果的那件事
    settled:已决阶段,事情已经有了一个结果,不管这个结果是好是坏,整件事情无法逆转

    事情总是从 未决阶段 逐步发展到 已决阶段的。并且,未决阶段拥有控制何时通向已决阶段的能力。

  2. ES6将事情划分为三种状态: pending、resolved、rejected

    pending: 挂起,处于未决阶段,则表示这件事情还在挂起(最终的结果还没出来)
    resolved:已处理,已决阶段的一种状态,表示整件事情已经出现结果,并是一个可以按照正常逻辑进行下去的结果
    rejected:已拒绝,已决阶段的一种状态,表示整件事情已经出现结果,并是一个无法按照正常逻辑进行下去的结果,通常用于表示有一个错误

    既然未决阶段有权力决定事情的走向,因此,未决阶段可以决定事情最终的状态!

    我们将 把事情变为resolved状态的过程叫做:resolve,推向该状态时,可能会传递一些数据

    我们将 把事情变为rejected状态的过程叫做:reject,推向该状态时,同样可能会传递一些数据,通常为错误信息

    始终记住,无论是阶段,还是状态,是不可逆的!

  3. 当事情达到已决阶段后,通常需要进行后续处理,不同的已决状态,决定了不同的后续处理。

    resolved状态:这是一个正常的已决状态,后续处理表示为 thenable
    rejected状态:这是一个非正常的已决状态,后续处理表示为 catchable

    后续处理可能有多个,因此会形成作业队列,这些后续处理会按照顺序,当状态到达后依次执行
    Promise全过程

Promise的基本使用

const pro = new Promise((resolve, reject)=>{
    // 未决阶段的处理
    // 通过调用resolve函数将Promise推向已决阶段的resolved状态
    // 通过调用reject函数将Promise推向已决阶段的rejected状态
    // resolve和reject均可以传递最多一个参数,表示推向状态的数据
})

pro.then(data=>{
    //这是thenable函数,如果当前的Promise已经是resolved状态,该函数会立即执行
    //如果当前是未决阶段,则会加入到作业队列,等待到达resolved状态后执行
    //data为状态数据
}, err=>{
    //这是catchable函数,如果当前的Promise已经是rejected状态,该函数会立即执行
    //如果当前是未决阶段,则会加入到作业队列,等待到达rejected状态后执行
    //err为状态数据
})

这里注意一些细节:

  1. 未决阶段的处理函数是同步的,会立即执行
  2. thenable和catchable函数是异步的,就算是立即执行,也会加入到事件队列中等待执行,并且,加入的队列是微队列
  3. pro.then可以只添加thenable函数,pro.catch可以单独添加catchable函数
  4. 在未决阶段的处理函数中,如果发生未捕获的错误,会将状态推向rejected,并会被catchable捕获
  5. 一旦状态推向了已决阶段,无法再对状态做任何更改
  6. Promise并没有消除回调,只是让回调变得可控

Promise对象中,无论是then方法还是catch方法,它们都具有返回值,返回的是一个全新的Promise对象,它的状态满足下面的规则:

  1. 如果当前的Promise是未决的,得到的新的Promise是挂起状态
  2. 如果当前的Promise是已决的,会运行响应的后续处理函数,并将后续处理函数的结果(返回值)作为resolved状态数据,应用到新的Promise中;如果后续处理函数发生错误,则把返回值作为rejected状态数据,应用到新的Promise中。

后续的Promise一定会等到前面的Promise有了后续处理结果后,才会变成已决状态

如果前面的Promise的后续处理,返回的是一个Promise,则返回的新的Promise状态和后续处理返回的Promise状态保持一致。

Promise中的其他api

原型成员 (实例成员)

  • then:注册一个后续处理函数,当Promise为resolved状态时运行该函数
  • catch:注册一个后续处理函数,当Promise为rejected状态时运行该函数
  • finally:注册一个后续处理函数(无参),当Promise为已决时运行该函数

构造函数成员 (静态成员)

  • resolve(数据):该方法返回一个resolved状态的Promise,传递的数据作为状态数据(如果传递的数据是Promise,则直接返回传递的Promise对象)

  • reject(数据):该方法返回一个rejected状态的Promise,传递的数据作为状态数据

  • all(iterable):这个方法返回一个新的promise对象,该promise对象在iterable参数对象里所有的promise对象都成功的时候才会触发成功,一旦有任何一个iterable里面的promise对象失败则立即触发该promise对象的失败。这个新的promise对象在触发成功状态以后,会把一个包含iterable里所有promise返回值的数组作为成功回调的返回值,顺序跟iterable的顺序保持一致;如果这个新的promise对象触发了失败状态,它会把iterable里第一个触发失败的promise对象的错误信息作为它的失败错误信息。Promise.all方法常被用于处理多个promise对象的状态集合。

  • race(iterable):当iterable参数里的任意一个子promise被成功或失败后,父promise马上也会用子promise的成功返回值或失败详情作为参数调用父promise绑定的相应句柄,并返回该promise对象

async 和 await

async 和 await 是 ES2016 新增两个关键字,它们借鉴了 ES2015 中生成器在实际开发中的应用,目的是简化 Promise api 的使用,并非是替代 Promise。

async

async 用于修饰函数(无论是函数字面量还是函数表达式),放置在函数最开始的位置,被修饰函数的返回结果一定是 Promise 对象。

async function test1(){
    console.log(1);
    return 2;
}

// 等效于
async function test2(){
    const result = await test1();
    console.log(result);
}
test2();

await

await关键字必须出现在async函数中!!!

await用在某个表达式之前,如果表达式是一个Promise,则得到的是thenable中的状态数据。如果await的表达式不是Promise,则会将其使用Promise.resolve包装后按照规则运行。

async function test1(){
    console.log(1);
    return 2;
}

async function test2(){
    const result = await test1();
    console.log(result);
}
test2();

// 等效于
function test1(){
    return new Promise((resolve, reject)=>{
        console.log(1);
        resolve(2);
    })
}

function test2(){
    return new Promise((resolve, reject)=>{
        test1().then(data => {
            const result = data;
            console.log(result);
            resolve();
        })
    })
}
test2();
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值