一、前言
Promise
灵魂三问:是什么?做什么?怎么做?
-
是什么?—-
Promise
是异步编程的一种解决方案,ES6新增的一个对象,用来传递异步操作的消息。它代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个事件提供统一的 API,可供进一步处理。 -
做什么?—-
Promise
解决回调地狱的问题,在多层嵌套的回调方法中,如果同时存在同步、异步的方法,那么实际执行顺序会混乱,不好调试不好维护。 -
怎么做?
3.1 假设有一个需求,对接服务端接口时,想要拿到接口url 为 ‘url5’ 返回的data5,但是url5需要根据url4返回的数据作为参数,url4又需要url3返回的数据作为参数,以此类推 ······(嵌套层级略微夸张了一点点,但实际开发中经常出现类似这种依赖上一个接口返回的数据作为下一个接口的传递参数)不使用
Promise
处理方案:$.get('/url1', function (data1) { $.get('/url2', data1, function (data2) { $.get('/url3', data2, function (data3) { $.get('/url4', data3, function (data4) { $.get('/url5', data4, function (data5) { console.log(data5) }) }) }) }) }) 复制代码
使用
Promise
处理方案:let promise = new Promise((resolve, reject) => { $.get('/url1', data1 => { resolve(data1) }) }) promise.then((data1) => { $.get('/url2', data1, data2 => { return data2 }) }).then((data2) => { $.get('/url3', data2, data3 => { return data3 }) }).then((data3) => { $.get('/url4', data3, data4 => { console.log(data4) }) }) 复制代码
二、Promise使用原理分析
Promise
就是一个类,在执行这个类的时候,需要传递一个执行器进去,执行器会立即执行Promise
中有三种状态,分别为 等待pending
, 成功fulfilled
,失败rejected
pending
->fulfilled
pending
->rejected
状态一旦确定就不可更改resolve
和reject
函数是用来更改状态的
resolve
:fulfilled
reject
:rejected
then
方法内部做的事情就判断状态 如果状态是成功就调用成功的回调函数 如果状态是失败,就调用失败的回调函数
then
方法是定义在原型对象当中then
成功回调有一个参数 表示成功之后的值then
失败回调用一个参数,表示失败后的原因
三、手写Pormise
- 创建
Mypromise.js
文件,根据上述1. 2. 3. 原理分析,我们定义三种状态,创建一个MyPromise
的类,执行器立即执行,初始化状态为PENDING
,定义resolve
,reject
方法,代码如下:
const PENDING = "pending" //等待
const FULFILLED = "fulfilled" //成功
const REJECT = "reject" //失败
class MyPromise {
constructor(executor) {
executor(this.resolve, this.reject)
}
// 初始状态 等待
status = PENDING
resolve = () => {
// 如果状态不是等待 阻止程序向下执行
if (this.status !== PENDING) return
// 将状态更改为成功
this.status = FULFILLED
}
reject = () => {
// 如果状态不是等待 阻止程序向下执行
if (this.status !== PENDING) return
// 将状态更改为失败
this.status = REJECT
}
}
复制代码
- 根据上诉4. 5.原理分析,我们需要定义
then
方法,主要是判断当前状态调用成功或者失败的函数,需要提前声明successCallback
和failCallback
分别为成功和失败的回调函数,回调函数中需要传递成功的值value
或者传递错误信息reason
,因此value
和reason
需要提前声明,代码如下:
// 声明成功返回的初始值
value = undefined
// 声明失败返回的原因
reason = undefined
// 声明成功回调函数
successCallback = undefined
// 声明失败回调函数
failCallback = undefined
then (successCallback, failCallback) {
if (this.status === FULFILLED) {
successCallback(this.value)
} else if (this.status === REJECT) {
failCallback(this.reason)
}
}
复制代码
因为我们then
方法中successCallback
和failCallback
回调函数中需要用上value
和reason
的值作为参数传递,所以我们应该在resolve
和reject
中分别保存接受到的value
和reason
,代码修改如下:
resolve = value => {
// 如果状态不是等待 阻止程序向下执行
if (this.status !== PENDING) return
// 将状态更改为成功
this.status = FULFILLED
// 保存成功之后的值,传递给then方法
this.value = value
}
reject = reason => {
// 如果状态不是等待 阻止程序向下执行
if (this.status !== PENDING) return
// 将状态更改为失败
this.status = REJECT
// 保存失败之后的原因,传递给then方法
this.reason = reason
}
复制代码
此时,基础简易版已经完成,需要module.exports = MyPromise
导出
四、最终代码和使用
MyPromise.js
const PENDING = "pending" //等待
const FULFILLED = "fulfilled" //成功
const REJECT = "reject" //失败
class MyPromise {
constructor(executor) {
executor(this.resolve, this.reject)
}
// 初始状态 等待
status = PENDING
// 声明成功返回的初始值
value = undefined
// 声明失败返回的原因
reason = undefined
// 声明成功回调函数
successCallback = undefined
// 声明失败回调函数
failCallback = undefined
resolve = value => {
// 如果状态不是等待 阻止程序向下执行
if (this.status !== PENDING) return
// 将状态更改为成功
this.status = FULFILLED
// 保存成功之后的值,传递给then方法
this.value = value
}
reject = reason => {
// 如果状态不是等待 阻止程序向下执行
if (this.status !== PENDING) return
// 将状态更改为失败
this.status = REJECT
// 保存失败之后的原因,传递给then方法
this.reason = reason
}
then (successCallback, failCallback) {
if (this.status === FULFILLED) {
successCallback(this.value)
} else if (this.status === REJECT) {
failCallback(this.reason)
}
}
}
module.exports = MyPromise
复制代码
创建index.js
导入我们的Pormise
类并使用它,代码如下:
const MyPromise = require('./MyPromise')
let promise = new MyPromise((resolve, reject) => {
resolve('成功值')
// reject('失败信息')
})
promise.then(value => {
console.log(value) // 成功值
}, reason => {
console.log(reason) // 失败信息
})
复制代码
在控制台中输入node index.js
启动
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END