ES6——异步处理与Promise

一、异步处理

ES官方参考了大量的异步场景,总结出了一套异步的通用模型,该模型可以覆盖几乎所有的异步场景,甚至是同步场景。
值得注意的是,为了兼容旧系统,ES6 并不打算抛弃掉过去的做法,只是基于该模型推出一个全新的 API,使用该API,会让异步处理更加的简洁优雅。
理解该 API,最重要的,是理解它的异步模型

1.两个阶段

ES6 将某一件可能发生异步操作的事情,分为两个阶段:unsettled 和 settled
在这里插入图片描述

unsettled: 未决阶段,表示事情还在进行前期的处理,并没有发生通向结果的那件事
settled:已决阶段,事情已经有了一个结果,不管这个结果是好是坏,整件事情无法逆转
事情总是从 未决阶段 逐步发展到 已决阶段的。并且,未决阶段拥有控制何时通向已决阶段的能力。

2.事情三种状态

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

pending: 挂起,处于未决阶段,则表示这件事情还在挂起(最终的结果还没出来)
resolved:已处理,已决阶段的一种状态,表示整件事情已经出现结果,并是一个可以按照正常逻辑进行下去的结果
rejected:已拒绝,已决阶段的一种状态,表示整件事情已经出现结果,并是一个无法按照正常逻辑进行下去的结果,通常用于表示有一个错误
既然未决阶段有权力决定事情的走向,因此,未决阶段可以决定事情最终的状态!
我们将 把事情变为resolved状态的过程叫做:resolve,推向该状态时,可能会传递一些数据
我们将 把事情变为rejected状态的过程叫做:reject,推向该状态时,同样可能会传递一些数据,通常为错误信息

始终记住,无论是阶段,还是状态,是不可逆的!
在这里插入图片描述

3.到达阶段后续处理

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

resolved状态:这是一个正常的已决状态,后续处理表示为 thenable
rejected状态:这是一个非正常的已决状态,后续处理表示为 catchable
后续处理可能有多个,因此会形成作业队列,这些后续处理会按照顺序,当状态到达后依次执行

在这里插入图片描述
整件事称之为Promise
在这里插入图片描述

二、Promise

1.基本使用

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为状态数据
});

例:

const pro = new Promise((resolve,reject) =>{
    console.log('未决阶段');
    resolve(12345);//推向已决resolved状态
});
pro.then(data =>{
    //处于已决resolved状态,后续的处理thenable
    console.log(data);
});

在这里插入图片描述

const pro = new Promise((resolve,reject) =>{
    console.log('未决阶段');
    reject(12345);//推向已决rejected状态
});
pro.then(data =>{
    
    console.log(data);
}, err =>{
	//处于已决rejected状态,后续的处理catchable
    console.log(err);
});

在这里插入图片描述

2.注意点

  1. 未决阶段的处理函数是同步的,会立即执行
const pro = new Promise((resolve, reject) => {
    console.log("未决阶段");
    console.log('推向resolved')
    resolve(123);
    console.log('马上结束')
});
pro.then(data => {
    // pro的状态是resolved
    console.log(data);
});
console.log('说完了');

在这里插入图片描述

  1. thenable和catchable函数是异步的,就算是立即执行,也会加入到事件队列中等待执行,并且,加入的队列是微队列
    面试题重点
const pro = new Promise((resolve, reject) => {
    console.log("未决阶段")
    resolve(123);//微队列
    setTimeout(() => {
        console.log("来个定时器")
    }, 0);//宏队列
    console.log('马上说完');
});
pro.then(data => {
    console.log(data);
});
pro.catch(err => {
    console.log(err);
});
console.log("没话说了");

在这里插入图片描述

  1. pro.then可以只添加thenable函数,pro.catch可以单独添加catchable函数
const pro = new Promise((resolve, reject) => {
    resolve(123);
})
pro.then(data => {
    console.log(data);
});
pro.catch(err => {
    console.log(err)
});
  1. 在未决阶段的处理函数中,如果发生未捕获的错误,会将状态推向rejected,并会被catchable捕获
const pro = new Promise((resolve, reject) => {
    throw new Error("123"); // 推向pro: rejected
    resolve(456);//不再执行
})
pro.then(data => {
    console.log(data);
});
pro.catch(err => {
    console.log(err)
});

在这里插入图片描述

  1. 一旦状态推向了已决阶段,无法再对状态做任何更改
const pro = new Promise((resolve, reject) => {
    throw new Error("abc");
    resolve(1); //无效
    reject(2); //无效
    resolve(3); //无效
    reject(4); //无效
})
pro.then(data => {
    console.log(data)
})
pro.catch(err => {
    console.log(err)
})
const pro = new Promise((resolve, reject) => {
    // throw new Error("abc");
    resolve(1);
    reject(2); //无效
    resolve(3); //无效
    reject(4); //无效
})
pro.then(data => {
    console.log(data)
})
pro.catch(err => {
    console.log(err)
})
  1. Promise并没有消除回调,只是让回调变得可控

3.事件和回调的优化

function biaobai(god) {
    return new Promise(resolve => {
        console.log(`我向${god}发出了表白短信`);
        setTimeout(() => {
            if (Math.random() < 0.1) {
                //女神同意拉
                resolve(true);
            } else {
                //无论是否同意,都是resolve,只有消息发不出去这种异常才是rejected
                resolve(false);
            }
        }, 1000);
    })
}

biaobai("女神1").then(result => {
    console.log(`女神1${result}`);
});
biaobai("女神2").then(result => {
    console.log(`女神2${result}`);
});

在这里插入图片描述

ajax({
    url: "./data/students.json?name=李华",
    ...
}).then(resp => {
    console.log(resp)
}, err => {
    console.log(err)
});
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞羽逐星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值