We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[toc]
//index.js let promise = new Promise((resolve,reject) => { resolve('成功')//成功值 reject('失败') }) promise.then(value => { console.log(value) }, reason => { console.log(reason) })
//newPromise.js const PENDING = 'pending' const FULFILLED = 'fulfilled' const REJECTED = 'rejected' class NewPromise { constructor(executor) { executor(this.resolve,this.reject) } //promise状态 status = PENDING value = undefined reason = undefined //值默认没有 resolve = value => { //如果状态不是等待,阻止程序向下执行 if(this.status !== PENDING)return this.status = FULFILLED this.value = value } //使用箭头函数的原因:直接调用一个普通函数,函数里面的this指向是undefined的 reject = reason => { if(this.status !== PENDING)return //将状态更改为失败 this.status = REJECTED this.reason = reason } //判断promise的状态,返回回调函数,需要传递value和reason then(successCallback,failCallback){ //判断状态 if(this.status === FULFILLED){ successCallback(this.value) }else if(this.status === REJECTED){ failCallback(this.reason) } } } module.exports = NewPromise
Promise 就是一个类,在执行这个类的时候,需要传递一个执行器进去,执行器会立即执行
... constructor(executor){ executor(this.resolve,this.reject) } //构造函数接收执行 ...
Promise 中有三种状态,分别为成功 fulfilled、失败 rejected、等待 pending
一旦状态确定就不可更改
graph LR pending --> fulfilled pending --> rejected
resolve: fulfilled reject: rejected
then方法内部做的事情就判断状态,如果状态是成功,调用成功的回调函数,如果状态是失败。 调用失败回调函数 then方法是被定义在原型对象中的
then作用:判断promise的状态,返回回调函数,需要传递value和reason
then成功回调有一个参数value,表示成功之后的值,then失败回调有一个参数reason,表示失败后的原因
示例,在执行器中加入异步代码
//index.js let promise = new Promise((resolve,reject) => { setTimeout(() => { resolve('成功') },2000) }) promise.then(value => { console.log(value) }, reason => { console.log(reason) })
//newPromise.js class NewPromise { ... successCallback = undefined failCallback = undefined //默认是undefined ... resolve = value => { //如果状态不是等待,阻止程序向下执行 if(this.status !== PENDING)return this.status = FULFILLED this.value = value //判断成功回调是否存在,如果存在 调用 this.successCallback && this.successCallback(this.value)//在更改状态函数里执行成功/失败回调 } //直接调用一个普通函数,函数里面的this指向是undefined的 reject = reason => { if(this.status !== PENDING)return //将状态更改为失败 this.status = REJECTED this.reason = reason //判断成功回调是否存在,如果存在 调用 this.failCallback && this.failCallback(this.reason)//在更改状态函数里执行成功/失败回调 } then(successCallback,failCallback){ //判断状态 if(this.status === FULFILLED){ successCallback(this.value) }else if(this.status === REJECTED){ failCallback(this.reason) }else{ //等待,临时存储成功和失败回调 //将成功回调和失败回调存储起来 this.successCallback = successCallback this.failCallback = failCallback } } ... }
当有多个then时,会有多个成功和失败回调,此时应该将保存的回调函数变成一个数组,在状态更改时依次取出并且传递一个成功值/失败结果给成功回调/失败回调
//index.js promise.then(value => { console.log(value) }) promise.then(value => { console.log(value) }) promise.then(value => { console.log(value) })
//将保存的回调函数变成一个数组 successCallback = [] failCallback = [] ... //this.successCallback && this.successCallback(this.value) while(this.successCallback.length){ this.successCallback.shift()(this.value) //shift()方法会移除并回传阵列的第一个元素 } ... { this.successCallback.push(successCallback) this.failCallback.push(failCallback) } ...
//index.js let promise = new Promise((resolve,reject) => { setTimeout(() => { resolve('成功') },2000) }) promise.then(value => { console.log(value) return 100 //链式调用then方法 }).then(value => { console.log(value) //value = 100 })
//newPromise.js then(successCallback, failCallback) { let promise2 = new NewPromise((resolve,reject) => { if (this.status === FULFILLED) { let x = successCallback(this.value) resolve(x) //传递的时一个普通值x的时候,调用resolve()方法,把这个普通纸传递给下一个promise2对象 } else if (this.status === REJECTED) { failCallback(this.reason) } else { this.successCallback.push(successCallback) this.failCallback.push(failCallback) } }) return promise2 //调用了then方法会返回一个promise,以便于下一次then可以继续链式调用 }
当链式调用的上一个then return的值不是一个普通值而是一个promise对象时
判断 x 的值是普通值还是promise对象
如果是普通值,直接调用resolve
如果是promise对象,查看promsie对象返回的结果
再根据promise对象返回的结果,决定调用resolve 还是调用reject
//index.js let promise = new NewPromise((resolve,reject) => { resolve('成功') }) function other(){ return new NewPromise((resolve,reject) => { resolve('other') }) } promise.then(value => { console.log(value) return other()//other是一个promise对象 }).then(value => { console.log(value) //value = other })
class NewPromise{ ... then(successCallback, failCallback) { let promise2 = new NewPromise((resolve,reject) => { if (this.status === FULFILLED) { let x = successCallback(this.value) resolvePromise(x,resolve,reject) //传递的时一个普通值x的时候,调用resolve()方法,把这个普通纸传递给下一个promise2对象,这里使用一个resolvePromise()方法去判断这个x是普通值还是promise对象 } else if (this.status === REJECTED) { failCallback(this.reason) } else { this.successCallback.push(successCallback) this.failCallback.push(failCallback) } }) return promise2 } ... } function resolvePromise(x,resolve,reject){ if(x instanceof NewPromise){ // x.then(value => resolve(value),reason => {reason})//查看状态 x.then(resolve,reject) }else{ resolve(x) } }
当then返回了当前的promise对象时,需要识别是否是自对象。
解决:在resolvePromise中判断当前传值x是否为当前priomise对象
//index.js let p1 = promise.then(value => { console.log(value) return p1 }) p1.then(value=>{ console.log(value) },reason => { console.log(reason) }) //promise的循环调用
function resolvePromise(promise2, x,resolve,reject){ if(promise2 === x){ return reject(new TypeError('Chaining cycle detected for promise #<Promise>')) } if(x instanceof NewPromise){ // x.then(value => resolve(value),reason => {reason})//查看状态 x.then(resolve,reject) }else{ resolve(x) } }
//在执行器中进行错误捕获 class NewPromise{ constructor(executor) { try{ executor(this.resolve, this.reject) }catch(e){ this.reject(e) } } ... }
注意,上一个then方法的错误在下一个then中捕获到
同理,不止要在执行器中进行错误捕获,在状态改变之后进行也要进行错误捕获
then(successCallback, failCallback) { let promise2 = new NewPromise((resolve, reject) => { if (this.status === FULFILLED) { setTimeout(() => { try { let x = successCallback(this.value) resolvePromise(promise2, x, resolve, reject) } catch (e) { reject(e) } }, 0) } else if (this.status === REJECTED) { try { failCallback(this.reason) } catch (e) { reject(e) } } else { this.successCallback.push(()=>{ successCallback() }) this.failCallback.push(() => { failCallback() }) //要对回调函数进行处理 } }) return promise2 }
当then不传递任何参数时,最新一个then获取的value还是上一个最新then传递的参数
promise .then() .then() .then(value => console.log(value)) //相当于 promise .then(value => value) .then(value => value) //一层层向后进行传递相同的内容 .then(value => console.log(value))
//NewPromise.js then(successCallback, failCallback){ successCallback = successCallback ? successCallback : value => value failCallback = failCallback ? failCallback : reason => reason }
static all (array) { let result = []; let index = 0; return new MyPromise((resolve, reject) => { function addData (key, value) { result[key] = value; index++; if (index === array.length) { resolve(result); } } for (let i = 0; i < array.length; i++) { let current = array[i]; if (current instanceof MyPromise) { // promise 对象 current.then(value => addData(i, value), reason => reject(reason)) }else { // 普通值 addData(i, array[i]); } } }) }
static resolve (value) { if (value instanceof MyPromise) return value; return new MyPromise(resolve => resolve(value)); //普通值:创建promise对象,传递一个执行器,使用resolve方法将value进行返回 }
无论当前Promise对象的执行结果是成功还是失败,finally()方法当中的回调函数始终会被执行一次
在finally()方法的后面可以链式调用then方法来拿到Promise对象最终返回的结果
不是静态方法,要定义在原型对象身上
finally (callback) { return this.then(value => { return MyPromise.resolve(callback()).then(() => value); //需要借助resolve,不管是普通值还是promise对象,都使用resolve转化为promise对象 //再使用then地成功回调方法返回一个value //这样就可以等待callback()的返回值,再去执行return value //避免setTimeout没走完就返回了value }, reason => { return MyPromise.resolve(callback()).then(() => { throw reason }) }) } //index.js function p1 () { return new MyPromise(function (resolve, reject) { setTimeout(function () { resolve('p1') }, 2000) }) } function p2 () { return new MyPromise(function (resolve, reject) { // reject('失败') resolve('p2 finally'); }) } p2().finally(()=> { console.log('finally') return p1() }).then(value => { console.log(value) //没等两秒之后就已经输出了 },reason => { console.log(reason) })
链式调用catch去处理reject()失败的情况
catch (failCallback) { return this.then(undefined, failCallback) //不传递成功回调,只传递失败回调 //return便于之后使用promise的其它方法 }
The text was updated successfully, but these errors were encountered:
No branches or pull requests
[toc]
Promise核心逻辑实现
示例
总结
Promise 就是一个类,在执行这个类的时候,需要传递一个执行器进去,执行器会立即执行
Promise 中有三种状态,分别为成功 fulfilled、失败 rejected、等待 pending
一旦状态确定就不可更改
then方法内部做的事情就判断状态,如果状态是成功,调用成功的回调函数,如果状态是失败。
调用失败回调函数 then方法是被定义在原型对象中的
then作用:判断promise的状态,返回回调函数,需要传递value和reason
then成功回调有一个参数value,表示成功之后的值,then失败回调有一个参数reason,表示失败后的原因
在Promise类中加入异步逻辑
示例,在执行器中加入异步代码
实现then方法多次调用添加多个处理函数
当有多个then时,会有多个成功和失败回调,此时应该将保存的回调函数变成一个数组,在状态更改时依次取出并且传递一个成功值/失败结果给成功回调/失败回调
then方法的链式调用
当链式调用的上一个then return的值不是一个普通值而是一个promise对象时
判断 x 的值是普通值还是promise对象
如果是普通值,直接调用resolve
如果是promise对象,查看promsie对象返回的结果
再根据promise对象返回的结果,决定调用resolve 还是调用reject
then方法链式调用识别Promise对象自返回
当then返回了当前的promise对象时,需要识别是否是自对象。
解决:在resolvePromise中判断当前传值x是否为当前priomise对象
捕获/处理错误
注意,上一个then方法的错误在下一个then中捕获到
同理,不止要在执行器中进行错误捕获,在状态改变之后进行也要进行错误捕获
将then方法的参数变成可选参数
当then不传递任何参数时,最新一个then获取的value还是上一个最新then传递的参数
Promise.all()
promise.resolve()
Promise.finally()
无论当前Promise对象的执行结果是成功还是失败,finally()方法当中的回调函数始终会被执行一次
在finally()方法的后面可以链式调用then方法来拿到Promise对象最终返回的结果
不是静态方法,要定义在原型对象身上
Promise.catch()
链式调用catch去处理reject()失败的情况
The text was updated successfully, but these errors were encountered: