「第五届青训营 」伴学笔记创作活动的第 5 天
前言
早期异步代码困境
众所周知,js是单线程的,耗时操作都是交给浏览器来处理,等时间到了从队列中取出执行,设计到事件循环的概念,笔者也分享过,可以看以下,理解了可以更好的理解promise。
我以一个需求为切入点,我模拟网络请求(异步操作)
如果网络请求成功了,你告知我成功了
如果网络请求失败了,你告知我失败了
早期解决方案
早期解决方案都是传入两个回调,一个失败的,一个成功的。 那很多开发者会问这不是挺好的吗?挺简单的,js中函数是一等公民,可以传来传去,但是这样太灵活了,没有规范。
- 如果使用的是框架,还要阅读一下框架源码,正确失败的传实参的顺序,如果传参顺序错误这样是非常危险的。
Promise
-
Promise(承诺),给予调用者一个承诺,过一会返回数据给你,就可以创建一个promise对象 -
当我们
new一个promise,此时我们需要传递一个回调函数,这个函数为立即执行的,称之为(executor) -
这个回调函数,我们需要传入两个参数回调函数,
reslove,reject(函数可以进行传参)-
当执行了
reslove函数,会回调promise对象的.then函数 -
当执行了
reject函数,会回调promise对象的.catche函数
-
promise的状态
-
首先先给大家举个栗子,把代码抽象为现实的栗子
- 你答应你女朋友,下周末带她去吃好吃的 (还未到下周末,此时状态为待定状态)
- 时间飞快,今天就是周末了,你和你女友一起吃了烤肉、甜点、奶茶...(已兑现状态)
- 时间飞快,今天就是周末了,正打算出门。不巧产品经理,因为线上出现的紧急问题,需要回公司解决一下,你(为了生活)只能委婉的拒绝一下女友,并且说明一下缘由(已拒绝状态)
-
使用
promise的时候,给它一个承诺,我们可以将他划分为三个阶段- pending(待定),执行了executor,状态还在等待中,没有被兑现,也没有被拒绝
- fulfilled(已兑现),执行了
resolve函数则代表了已兑现状态 - rejected(已拒绝),执行了
reject函数则代表了已拒绝状态
-
首先,状态只要从待定状态,变为其他状态,则状态不能再改变
思考以下代码:
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
reject('失败')
resolve('成功')
}, 3000);
})
promise.then(res => console.log(res)).catch(err => console.log(err))
//失败
-
当我调用
reject之后,在调用resolve是无效的,因为状态已经发生改变,并且是不可逆的。
总结
Promises在过去几年是一个非常火爆的话题,它甚至从JavaScript里抽离出来变成了一个语言架构。相信很快我们将见到有愈来愈多的JavaScript API将使用以promise为基础的模式,学会promise的用法能简化你在JavaScript中的操作。