另一篇文章: JS——Promise题目篇幅过长,这篇需要了解东西也多,因此分离出来。
前言
深入了解过 Promise 的人都知道,Promise 所说的异步执行,只是将 Promise 构造函数中 resolve,reject 方法和注册的 callback 转化为 eventLoop的 microtask/Promise Job,并放到 Event Loop 队列中等待执行,也就是 Javascript 单线程中的“异步执行”。
(microtask其实就是微任务)
Promise的大体框架
promise有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)
Promise的大体框架:
1、Promise构造函数:Promise(excutor) { }
excutor函数:同步执行 (resolve,reject) => { }
resolve函数:内部定义成功时我们调用的函数 value =>{ }
reject函数:内部定义失败时我们调用的函数 reason => { }
2、Promise.propotype.then方法:(onFulfilled, onRejected) => { }
onFulfilled函数:成功的回调函数 (value) => { }
onRejected函数:失败的回调函数 (reason) => { }
说明:then返回一个新的Promise。
3、Promise.prototype.catch方法:(onRejected) => { }
onRejeted函数:return this.then(null, onRejected)
,其实是.then()的简写
// 1、Promise构造函数
function Promise(excutor) {
// resolve(value) { }
function resolve(value) { }
// reject(reason) { }
function reject(reason) { }
// excutor(resolve,reject)
try {
excutor(resolve, reject)
} catch (err) {
reject(err)
}
}
// 2、Promise.propotype.then()
Promise.prototype.then = function (onFulfilled, onRejected) {
let self = this
if (self.status === 'fulfilled') {
return new Promise((resolve, reject) => {
try {
...
} catch (err) {
reject(err)
}
})
}
if (self.status === 'rejected') {
return new Promise((resolve, reject) => {
try {
...
} catch (err) {
reject(err)
}
})
}
if (self.status === 'pending') {
return new Promise((resolve, reject) => {
...
})
}
}
// 3、Promise.prototype.catch()
Promise.prototype.catch = function(onRejected) {
return this.then(null, onRejected)
}
Promise构造函数实现
1、定义一个常量用来存this的指向。let self = this
2、定义一个状态属性 status、定义两个用来存数据的属性、定义两个用来缓存回调函数 callbacks。状态 self.status = 'pending'、'fulfilled'、'rejected'
存数据 self.value、self.reason
缓存回调函数 self.onFulfilledCallbacks = [] self.onRejectedCallbacks = []
3、定义两个用于改变Promise状态的函数 resolve 和 reject
4、函数里面:首先判断当前状态是不是 ‘pending’ 状态,如果是则直接返回,因为在promise中状态只能改变一次。其次改变当前的状态为对应的状态,再存入当前的数据。最后判断如果有待执行的callback函数,立即异步执行回调函数onResolved()/onRejected()
5、try catch 用来捕获异常
function Promise(excutor) {
let self = this
self.status = 'pending'
self.value = null
self.reason = null
self.onFulfilledCallbacks = []
self.onRejectedCallbacks = []
function resolve(value) {
if (self.status === 'pending') {
self.value = value
self.status = 'fulfilled'
self.onFulfilledCallbacks.forEach(item => item())
}
}
function reject(reason) {
if (self.status === 'pending') {
self.reason = reason
self.status = 'rejected'
self.onRejectedCallbacks.forEach(item => item())
}
}
try {
excutor(resolve, reject)
} catch (err) {
reject(err)
}
}
Promise.then()方法和catch()方法的实现
1、判断回调函数的类型:是函数,则继续向下传递;否则直接resolve( )或throw err。
2、定义一个常量,用来获取this的指向 let self = this
3、链式调用,当执行完then后可以继续执行then,其实它的原理就是通过返回一个新的Promise实现的。
then方法接收的两个函数中,可以通过return把值传给下一个步,也可以返回一个新的Promise把值传给下一步,then方法执行的时候有个特点,就是为了保证链式调用,上一次then中不管你是成功还是失败都会把参数作为下一个then中成功时回调的参数
Promise.prototype.then = function (onFulfilled, onRejected) {
// 判断回调函数的类型
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => {resolve(value)}
onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw err}
let self = this
if (self.status === 'fulfilled') {
return new Promise((resolve, reject) => {
try {
let x = onFulfilled(self.value)
if (x instanceof Promise) {
x.then(resolve, reject)
} else {
resolve(x)
}
} catch (err) {
reject(err)
}
})
}
if (self.status === 'rejected') {
return new Promise((resolve, reject) => {
try {
let x = onRejected(self.reason)
if (x instanceof Promise) {
x.then(resolve, reject)
} else {
resolve(x)
}
} catch (err) {
reject(err)
}
})
}
if (self.status === 'pending') {
return new Promise((resolve, reject) => {
self.onFulfilledCallbacks.push(() => {
let x = onFulfilled(self.value)
if (x instanceof Promise) {
x.then(resolve, reject)
} else {
resolve(x)
}
})
self.onRejectedCallbacks.push(() => {
let x = onRejected(self.reason)
if (x instanceof Promise) {
x.then(resolve, reject)
} else {
resolve(x)
}
})
})
}
}
Promise.prototype.catch = function(onRejected) {
return this.then(null, onRejected)
}
完整代码
// 1、Promise构造函数
function Promise(excutor) {
let self = this
self.status = 'pending'
self.value = null
self.reason = null
self.onFulfilledCallbacks = []
self.onRejectedCallbacks = []
function resolve(value) {
if (self.status === 'pending') {
self.value = value
self.status = 'fulfilled'
self.onFulfilledCallbacks.forEach(item => item())
}
}
function reject(reason) {
if (self.status === 'pending') {
self.reason = reason
self.status = 'rejected'
self.onRejectedCallbacks.forEach(item => item())
}
}
try {
excutor(resolve, reject)
} catch (err) {
reject(err)
}
}
// 2、Promise.prototype.then()
Promise.prototype.then = function (onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => {resolve(value)}
onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw err}
let self = this
if (self.status === 'fulfilled') {
return new Promise((resolve, reject) => {
try {
let x = onFulfilled(self.value)
if (x instanceof Promise) {
x.then(resolve, reject)
} else {
resolve(x)
}
} catch (err) {
reject(err)
}
})
}
if (self.status === 'rejected') {
return new Promise((resolve, reject) => {
try {
let x = onRejected(self.reason)
if (x instanceof Promise) {
x.then(resolve, reject)
} else {
resolve(x)
}
} catch (err) {
reject(err)
}
})
}
if (self.status === 'pending') {
return new Promise((resolve, reject) => {
self.onFulfilledCallbacks.push(() => {
let x = onFulfilled(self.value)
if (x instanceof Promise) {
x.then(resolve, reject)
} else {
resolve(x)
}
})
self.onRejectedCallbacks.push(() => {
let x = onRejected(self.reason)
if (x instanceof Promise) {
x.then(resolve, reject)
} else {
resolve(x)
}
})
})
}
}
// 3、Promise.prototype.catch()
Promise.prototype.catch = function(onRejected) {
return this.then(null, onRejected)
}