Promise
一、promise的简略应用
new Promise((resolve, reject) => { resolve("ok")}).then(data => { console.log(data) //OK}, error => { console.log(error)})
//简化下let promise = new Promise(executor)promise.then(onFulfilled, onRejected)
须要留神的是
executor
是一个会被立刻执行的回调函数, 该函数带有两个参数,resolve
和reject
- 如果
executor
中调用了resolve(value)
,那么这个value
则会被传给onFulfilled
, 如第一个例子中console.log(data)
输入为ok
- 如果
executor
中调用了reject(value)
,那么这个value
则会被传给onRejected
,作为onRejected
的实参 - 还有一点须要留神的是,promise是带有状态的,开始默认为pending,当调用
resolve
后,状态变更为fulFilled
,当调用reject
后,状态变更为rejected
。当状态从pending
变更为fulFilled / reject
后,状态不可再扭转
二、Promise 的高级实现
让咱们持续带着第一个用例 来做个promise的高级实现
new Promise((resolve, reject) => { resolve("ok")}).then(data => { console.log(data) //OK}, error => { console.log(error)})
// 咱们带着例子逐行实现// let executor = (resolve, reject) => { resolve("ok") }// new Promise(executor)class Promise { constructor(executor){ this.status = "pending" //状态默认为期待态 //executor = (resolve, reject) => { resolve("ok") } //传入的executor是一个带有两个参数的函数, //并且参数resolve和reject都是可调用的函数 //所以咱们应该先申明这两个函数 而后当成实参传入 executor const resolve = (value) => { } const reject = (error) => { } executor(resolve,reject) } }
// let executor = (resolve, reject) => { resolve("ok") }// new Promise(executor)class Promise { constructor(executor){ this.status = "penging" this.resValue = null this.rejValue = null // executor = (resolve, reject) => { resolve("ok") } const resolve = (value) => { // 如 resolve("ok") 中传入的"ok" // 须要在前面代码的then的onFulilled中拿,故须要存储这个 value this.resValue = value // 并且调用resolve后,状态更改为fulfilled if(this.status === "pending"){ this.status = "fulfilled" } } const reject = (error) => { this.rejValue = error if(this.status === "pending"){ this.status = "rejected" } } executor(resolve,reject) } }
// let promise = new Promise(executor)// promise.then(onFulfilled, onRejected)// 能够得出 promise 须要一个 then 办法class Promise { constructor(executor){ // 如上... } then(onFulfilled, onRejected){ //调用then办法的时候,要判断是以后状态是胜利还是失败 if(this.status === "fulfilled"){ //如果以后是胜利态 onFulfilled(this.value) } if(this.status === "rejected"){ //如果以后是失败态 onRejected(this.error) } }}
这样算是根本实现了promise 的高级性能,然而当new promise(executor)
传入的executor
为异步函数的时候,就会呈现问题。如下:
new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve("ok") },0)}).then(data => { console.log(data) //不会输入ok})
// 其起因是:当 executor为异步函数传入new Promise`时// 尽管立刻调用了executor,然而其为异步函数,会被推入微工作,不会马上执行// 所以上面这个resolve 不会马上执行,会先执行宏工作的 then 办法// 所以在执行then 办法的时候,promise的状态依然为 pendingclass Promise { constructor(executor){ // executor = setTimeout(()=>{resolve("ok")},0) const resolve = (value) => { // ** 2. 后执行 this.value = value if(status === "pending"){ this.status = "fulfilled" } } // ... executor(resolve,reject) } then(onFulfilled, onRejected){ // ** 1. 先执行 if(this.status === "fulfilled"){ onFulfilled(this.value) } // ... } }
Promise 的高级实现之异步改良
当初的问题是, 在传入异步函数的时候,咱们执行到then
办法的时候, 状态还是为pending
,所以无奈执行到onFulfilled
。咱们又须要在executor
中调用了resolve
后执行onFulfilled
。所以很天然的想到了应用公布订阅模式来解决。即在then
中判断到以后为期待态时(那executor
肯定是异步函数), 将onFulfilled
和onRejected
存起来, 在executor
中执行到resolve后 执行onFulfilled
。 上面是代码实现:
class Promise { constructor(executor){ this.status = "pending" //onFulfilled汇合 this.onFulfilledCallbacks = [ ] //onRejected汇合 this.onRejectedCallbacks = [ ] const resolve = (value) => { this.resValue = value if(status === "pending"){ this.status = "fulfilled" // 公布 this.onFulfilledCallbacks.forEach(callback => { callback(this.value) }) } } const reject = (error) => { this.rejValue = error if(status === "pending"){ this.status = "rejected" this.onRejectedCallbacks.forEach(callback => { callback(this.error) }) } } executor(resolve,reject) } then(onFulfilled, onRejected){ // 同步代码不变,减少异步状况代码 if(this.status === "fulfilled"){ onFulfilled(this.value) } if(this.status === "rejected"){ onRejected(this.error) } // 新增代码 if(this.status === "pending"){ // 曾经到then了,status的状态还没有扭转。 // 阐明 executor 中为异步函数 // 订阅 this.onFulfilledCallbacks.push((data)=>{ //切片 onFulfilled(data) }) this.onRejectedCallbacks.push((error)=>{ onRejected(error) }) } }}
以上就是promise 的高级实现,promise的外围在于他们链式调用。咱们在下一章具体介绍
三、理解promise的链式调用
new Promise((resolve,reject) => { resolve("hello") }).then(data => { console.log(data) //hello return "world" }).then(data => { console.log(data) //world })
如果在then 中return
一个简略值(非promise
),那么将在下一个 then 中的onFulfilled
取到这个值。
new Promise((resolve,reject) => { resolve("hello") }).then(data => { throw new Error() }).then(data => { console.log(data) },error => { console.log(error) // Error })
如果在then中抛出异样,那么将会在下一个then的onRejected
拿到这个异样。
let promise1 = new Promise((resolve,reject) => { resolve("hello") }).then(data => { return data }) console.log(promise1) // Promise{<fulfilled>: "hello"} // 能够看得出来: 在then办法中,会返回一个promise对象 // 因为promise的状态不可二次扭转, 所以返回的应该是一个新的promise对象
四、测试案例剖析
在实现promise的链式调用前, 首先要有个测试案例:
let promise1 = new Promise((resolve, reject) => { setTimeout(() => { resolve("the message is ") }, 0);})
let promise2 = promise1.then(data => { let interPromise = new Promise((resolve,reject) => { setTimeout(() => { resolve(data + "that today is a happy day") }, 0); }) return interPromise}, null)
我感觉有必要先剖析下这个 promise2
- 1.首先咱们晓得这个
promise1.then()
肯定是返回一个新的promise
,而且是一个带着实现或完结态的promise
- 2.所以在
then
的外部生成一个promise
,并且在外部实现了这个promise
的resolve(data)
,而且这个data
来之外部的interPromise
的resolve()
- 3.再看下这个
interPromise
, 他要想把外部的resolve(data + "that today is a happy day")
里的数据传给下层then
的promise
,那么只能是隐性的调用interPromise
的then
,并且在这个then
中, 调用下层promise
的resolve
- 这是
promise
中的最难点,如果没看懂,能够多看几遍,糊涂的话能够先看上面的代码实现,再回过头来看这段剖析
let promise3 = promise2.then(data => { console.log(data) // expect: the message is that today is a happy day})
六、promise的链式调用
该案例为了不便浏览和了解,就实现了最难的性能,并且省略了异样捕捉等内容。
// constructor不变,只对then办法进行了批改class Promise { constructor(executor) { this.status = "pending" this.resValue = null this.rejValue = null this.onfulfilledCallbacks = [] this.onrejectedCallbacks = [] const resolve = (value) => { this.resValue = value if (this.status === "pending") { this.status = "fulfilled" this.onfulfilledCallbacks.forEach(callback => { callback(this.resValue) }) } } const reject = (error) => { this.rejValue = value if (this.status === "pending") { this.status = "rejected" this.onrejectedCallbacks.forEach(callback => { callback(this.rejValue) }) } } executor(resolve, reject) } then(onFulfilled, onRejected) { // onFulfilled = data => new Promise(...) //then 办法返回promise2 const promise2 = new Promise( (resolve2,reject2) => { if (this.status === "pending") { //async //这里须要一个实现一个异步 //因为在resolvePromise中须要 实现初始化的promise2 setTimeout(()=>{ this.onfulfilledCallbacks.push(data => { //代入案例来看 //这个x = interPromise let x = onFulfilled(data) //而后判断这个x 是否是一个 promise resolvePromise(x, resolve2, reject2) }) this.onrejectedCallbacks.push(error => { // 类比下面进行批改,这里不做批改 onRejected(error) }) },0) } // 上面状况和下面同理,我不做批改 if (this.status === "fulfilled") { onFulfilled(this.resValue) } if (this.status === "rejected") { onRejected(this.rejValue) } }) return promise2 }}function resolvePromise(x, resolve2, reject2){ // 源码中有许多判断的异样捕捉,这里就实现最外围的代码 if((typeof x === "object" && typeof x !== "null")|| typeof x === "function"){ // x is a object or function let then = x.then if(typeof then === "function"){ // 在这里调用interPromise的then // 并且调用下层promise的resolve then.call(x,data => resolve2(data),null) // x is a promise // for example: x = new promise((resolve,reject) => {resolve("ok")}) } }}