一、Promise
1.基本用法
// Promise 基本示例
const promise = new Promise(function (resolve, reject){
// 这里用于“兑现”承诺
// resolve(100)
reject(new Error('promise rejected'))
})
promise.then(function (value){
console.log('resolved', value)
}, function (error) {
console.log('error', error)
})
2.使用案例
// Promise 方式的 Ajax
function ajax(url) {
return new Promise(function (resolve, reject){
var xhr = new XMLHttpRequest()
xhr.open('GET', url)
xhr.responseType = 'json'
xhr.onload = function () {
if (this.status === 200) {
resolve(this.response)
} else {
reject(new Error(this.statusText))
}
}
xhr.send()
})
}
ajax('/api/users.json').then(function (res) {
console.log(res)
}, function (error) {
console.log(error)
})
3.Promise链式调用
-
Promise 对象的then方法会返回一个全新的 Promise 对象
-
后面的 then 方法就是为上一个then返回的 Promise 注册回调
-
前面 then 方法中回调函数的返回值会作为后面then方法回调的参数
-
如果回调中返回的是Promise,那后面的then方法的回调会等待它的结束
let promise = new Promise(resolve => {
console.log(1)
resolve(1)
})
promise.then((v) => {
console.log('2: ', v)
return 2
}).then((v) => {
console.log('3: ', v)
})
/* 输出为:
1
2: 1
3: 2
*/
4.异常处理
let promise1 = new Promise(resolve => {
console.log(1)
resolve(1)
})
promise1.then((v) => {
console.log('2: ', v)
return 2
}).then((v) => {
throw Error('error message')
console.log('3: ', v)
}, err => {
console.log(err)
})
输出是:
可以发现当此then的resolve成功函数中如果发生错误,无法被捕获,因为then中的reject失败回调只会捕获then 调用者的异常。
let promise1 = new Promise(resolve => {
console.log(1)
resolve(1)
})
promise1.then((v) => {
console.log('2: ', v)
return 2
}).then((v) => {
throw Error('error message')
console.log('3: ', v)
}).catch(err => {
console.log('error message')
})
输出为:
可以发现异常被正常捕获了,所以建议Promise的链式调用中使用catch进行错误处理,catch的错误捕获可以看作是整条调用链上的错误捕获
5.Promise并行
// Promise 并行执行
function ajax(url) {
return new Promise(function (resolve, reject){
var xhr = new XMLHttpRequest()
xhr.open('GET', url)
xhr.responseType = 'json'
xhr.onload = function () {
if (this.status === 200) {
resolve(this.response)
} else {
reject(new Error(this.statusText))
}
}
xhr.send()
})
}
// ajax('/api/users.json')
// ajax('/api/posts.json')
// 并行
var promise = Promise.all([
ajax('/api/users.json'),
ajax('/api/posts.json')
])
promise.then(function (values) {
console.log(values)
}).catch(function (err) {
console.log(err)
})
// 并行和串行
ajax('/api/urls.json').then(value => {
const urls = Object.values(value)
const tasks = urls.map(url => ajax(url))
return Promise.all(tasks)
}).then(values => {
console.log(values)
})
另一个并行方法是 Promise.race(),与Promise.all()的区别是:all方法是所有promise执行完成后返回结果,race是第一个promise执行完成后就返回结果
const request = ajax('/api/posts.json')
const timeout = new Promise((resolve, reject) => {
setTimeout(() => reject(new Error('timeout')), 500)
})
Promise.race([request, timeout]).then(value => {
console.log(11, value)
}).catch(error => console.log(error))
6.Generator生成器函数
- 基本使用
// 比普通函数多一个*
function * foo (){
console.log('start')
}
// 调用后不会立即执行
const r = foo()
// 执行next()方法后才会向下执行
r.next()
function * foo1 (){
// yield后面的值,可以通过执行到这一步的next()返回值得到
yield 'bar'
}
const r1 = foo1()
const bar = r1.next()
console.log(bar)
function * foo2 (){
// 这里可以获取到下一步的next()中传入的值
const res = yield 'bar'
console.log('res: ', res)
}
const r2 = foo2()
r2.next()
r2.next('ba1')
console.log(bar)
- 迭代器执行
// Promise 并行执行
function ajax(url) {
return new Promise(function (resolve, reject){
var xhr = new XMLHttpRequest()
xhr.open('GET', url)
xhr.responseType = 'json'
xhr.onload = function () {
if (this.status === 200) {
resolve(this.response)
} else {
reject(new Error(this.statusText))
}
}
xhr.send()
})
}
function * main() {
try {
const users = yield ajax('/api/users.json')
console.log(users)
const posts = yield ajax('/api/posts.json')
console.log(posts)
const users11 = yield ajax('/api/users11.json')
console.log(users11)
} catch (e) {
console.log(e)
}
}
// const result = g.next()
//
// result.value.then(data => {
// const result2 = g.next(data)
// if (result.done) return
// result2.value.then(data => {
// const result3 = g.next(data)
// if (result3.done) return
// result3.value.then(data => {
// g.next(data)
// })
// })
// })
// 执行器
function co(generator){
const g = generator()
function handleResult (result) {
if(result.done) return // 生成器函数结束
result.value.then(data => {
handleResult(g.next(data))
}, error => {
g.throw(error)
})
}
handleResult(g.next())
}
co(main)
7.Async/Await 语法糖
function ajax(url) {
return new Promise(function (resolve, reject){
var xhr = new XMLHttpRequest()
xhr.open('GET', url)
xhr.responseType = 'json'
xhr.onload = function () {
if (this.status === 200) {
resolve(this.response)
} else {
reject(new Error(this.statusText))
}
}
xhr.send()
})
}
async function main() {
try {
const users = await ajax('/api/users.json')
console.log(users)
const posts = await ajax('/api/posts.json')
console.log(posts)
const users11 = await ajax('/api/users11.json')
console.log(users11)
} catch (e) {
console.log(e)
}
}
const promise = main()
promise.then(() => {
console.log('complate')
})
二、手写Promise
1.Promise 核心逻辑实现
- 分析:
1.Promise 就是一个类 在执行这个类的时候,需要传递一个执行器,执行器会立即执行
2.Promise 有三种状态:成功fulfilled、失败rejected、等待pending。
状态变化只有两种情况,且一旦确定就不可修改:
pending -> fulfilled
pending -> rejected
3.resolve和reject函数是用来更改状态的
resolve: fulfilled
reject: rejected
4.then方法内部做的事情就是判断状态,如果状态是成功,调用成功的回调函数,
如果是失败,调用失败的回调函数。then方法是定义在原型对象上的方法
5.then成功回调有一个参数,表示成功之后的值;then失败回调有一个参数,表示失败的原因
- 实现
const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败
class MyPromise {
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
}
reject = reason => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return
// 将状态改为失败
this.status = REJECTED;
// 保存失败后的原因
this.reason = reason
}
then (successCallBack, failCallBack) {
// 判断状态
if (this.status === FULFILLED) {
successCallBack(this.value)
} else if (this.status === REJECTED) {
failCallBack(this.reason)
}
}
}
module.exports = MyPromise;
- 验证
const myPromise = require('./myPromise')
const promise = new myPromise((resolve, reject) => {
resolve('成功')
reject('失败')
})
promise.then(value => {
console.log(value)
}, reason => {
console.log(reason)
})
- 结果
2.Promise 类中加入异步逻辑
- 场景:
如下代码所示,将resolve调用延时执行的时候,会发现没有结果输出,是因为创建时传入的执行器立即执行了,但是主程序不会等待2s后再去调用resolve方法。这时调用then方法,状态 status 的值为pending,所以没有任何输出。
const promise = new myPromise((resolve, reject) => {
setTimeout(() => {
resolve('成功')
}, 2000)
})
promise.then(value => {
console.log(value)
}, reason => {
console.log(reason)
})
- 修改MyPromise
在then方法中,如果状态 status 的值是pending,保存成功和失败的回调函数,等2s后执行resolve或者reject方法时,再去执行保存的回调函数。
const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败
class MyPromise {
constructor(executor) {
executor(this.resolve, this.reject)
}
// promise 状态
status = PENDING;
// 成功之后的值
value = undefined;
// 失败后的原因
reason = undefined;
// 成功回调
successCallback = undefined;
// 失败回调
failCallback = undefined;
resolve = value => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return
// 将状态改为成功
this.status = FULFILLED;
// 保存成功之后的值
this.value = value
// 判断成功回调是否存在,如果存在就调用
this.successCallback && this.successCallback(value)
}
reject = reason => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return
// 将状态改为失败
this.status = REJECTED;
// 保存失败后的原因
this.reason = reason
// 判断失败回调是否存在,如果存在就调用
this.failCallback && this.failCallback(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;
}
}
}
module.exports = MyPromise;
3.适配then方法被多次调用
- 场景
如下代码所示,then方法是可以被多次调用的:
const promise = new myPromise((resolve, reject) => {
setTimeout(() => {
resolve('成功')
}, 2000)
})
promise.then(value => {
console.log(value)
}, reason => {
console.log(reason)
})
promise.then(value => {
console.log(value)
}, reason => {
console.log(reason)
})
promise.then(value => {
console.log(value)
}, reason => {
console.log(reason)
})
执行会发现只输出一个成功,因为我们保存的成功或失败回调函数只有一个,所以我们需要把之前保存回调的两个变量successCallback 和 failCallback改成数组,在赋值的时候使用push方法进行保存,最后调用的时候使用shift方法从前到后依次执行:
const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败
class MyPromise {
constructor(executor) {
executor(this.resolve, this.reject)
}
// promise 状态
status = PENDING;
// 成功之后的值
value = undefined;
// 失败后的原因
reason = undefined;
// 成功回调
successCallback = [];
// 失败回调
failCallback = [];
resolve = value => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return
// 将状态改为成功
this.status = FULFILLED;
// 保存成功之后的值
this.value = value
// 判断成功回调是否存在,如果存在就调用
while (this.successCallback.length) this.successCallback.shift()(this.value)
// this.successCallback && this.successCallback(value)
}
reject = reason => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return
// 将状态改为失败
this.status = REJECTED;
// 保存失败后的原因
this.reason = reason
// 判断失败回调是否存在,如果存在就调用
while (this.failCallback.length) this.failCallback.shift()(this.reason)
// this.failCallback && this.failCallback(reason)
}
then (successCallBack, failCallBack) {
// 判断状态
if (this.status === FULFILLED) {
successCallBack(this.value)
} else if (this.status === REJECTED) {
failCallBack(this.reason)
} else {
// 等待状态
// 将成功回调和失败回调保存
this.successCallback.push(successCallBack);
this.failCallback.push(failCallBack);
}
}
}
module.exports = MyPromise;
4.then方法的链式调用
- 场景:
如下代码所示,then方法是可以进行链式调用的
const promise = new myPromise((resolve, reject) => {
resolve('成功')
})
promise.then(value => {
console.log(value)
return 100;
}).then(value => {
console.log(value)
})
既然要链式调用then方法,那么then方法的返回值就必须是MyPromise对象,因为需要接收上一个then方法中成功回调函数的返回值,那么就应该接收该返回值,并且传给新建的MyPromise对象的resolve方法。then方法的代码如下所示:
then (successCallBack, failCallBack) {
let promise2 = new MyPromise((resolve, reject) => {
// 判断状态
if (this.status === FULFILLED) {
let x = successCallBack(this.value)
resolve(x)
} else if (this.status === REJECTED) {
failCallBack(this.reason)
} else {
// 等待状态
// 将成功回调和失败回调保存
this.successCallback.push(successCallBack);
this.failCallback.push(failCallBack);
}
});
return promise2;
}
上面的处理是针对上一个then方法返回值是常量的情况,如果返回的是Promise对象呢,判断x的值是普通值,还是promise对象,修改then方法:
then (successCallBack, failCallBack) {
let promise2 = new MyPromise((resolve, reject) => {
// 判断状态
if (this.status === FULFILLED) {
let x = successCallBack(this.value)
// 判断x的值是普通值,还是promise对象
// 如果是普通值,直接调用resolve
// 如果是promise对象,根据promise对象返回的结果,
// 决定调用resolve,还是调用reject
resolvePromise(x, resolve, reject)
} 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 MyPromise) {
// promise对象
// x.then(value => resolve(value), reason => reject(reason))
// 简化
x.then(resolve, reject)
} else {
// 普通值
resolve(x)
}
}
5.错误处理
- 场景:
then方法中返回当前promise,发生循环调用的错误,如下代码所示:
const promise = new Promise((resolve, reject) => {
resolve('成功')
})
let p1 = promise.then(value => {
console.log(value)
return p1;
})
- 运行结果
提示发生了链式循环的错误,现在处理我们也需要处理一下,我们只需要在then方法的resolve中,判断当前promise2是否和x相同,相同就需要报错。
then (successCallBack, failCallBack) {
let promise2 = new MyPromise((resolve, reject) => {
// 判断状态
if (this.status === FULFILLED) {
// 这里需要放在setTimeout中,是因为promise2需要等待new MyPromise执行完成后才能得到值
setTimeout(() => {
let x = successCallBack(this.value)
// 判断x的值是普通值,还是promise对象
// 如果是普通值,直接调用resolve
// 如果是promise对象,根据promise对象返回的结果,
// 决定调用resolve,还是调用reject
resolvePromise(x, resolve, reject, promise2)
}, 0)
} else if (this.status === REJECTED) {
failCallBack(this.reason)
} else {
// 等待状态
// 将成功回调和失败回调保存
this.successCallback.push(successCallBack);
this.failCallback.push(failCallBack);
}
});
return promise2;
}
辅助函数中判断:
function resolvePromise(x, resolve, reject, promise2) {
if(promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if(x instanceof MyPromise) {
// promise对象
// x.then(value => resolve(value), reason => reject(reason))
// 简化
x.then(resolve, reject)
} else {
// 普通值
resolve(x)
}
}
- 测试:
const promise = new myPromise((resolve, reject) => {
resolve('成功')
})
let p1 = promise.then(value => {
console.log(value)
return p1;
})
p1.then(value => {
console.log(value)
}, reason => {
console.log(reason.message)
})
- 运行结果
6.捕获错误
- 如果我们执行的Promise代码中有错误,应该怎么捕获呢,如下代码所示:
const myPromise = require('./myPromise')
const promise = new myPromise((resolve, reject) => {
// resolve('成功')
throw new Error('错误')
})
promise.then(value => {
console.log(value)
}, reason => {
console.log(reason.message)
})
直接在构造方法中使用try...catch进行捕获即可:
constructor(executor) {
try {
executor(this.resolve, this.reject)
} catch (e) {
this.reject(e)
}
}
- 如果then的回调函数报错了,怎么处理,如下代码所示
const myPromise = require('./myPromise')
const promise = new myPromise((resolve, reject) => {
resolve('成功')
// throw new Error('错误')
})
promise.then(value => {
console.log(value)
throw new Error('then 报错')
}, reason => {
console.log(reason.message)
}).then(value => {
console.log(value)
}, reason => {
console.log(reason.message)
})
直接将then中的成功回调用try...catch包起来,错误时,调用下一个then的reject方法,如下代码所示:
then (successCallBack, failCallBack) {
let promise2 = new MyPromise((resolve, reject) => {
// 判断状态
if (this.status === FULFILLED) {
// 这里需要放在setTimeout中,是因为promise2需要等待new MyPromise执行完成后才能得到值
setTimeout(() => {
try {
let x = successCallBack(this.value)
// 判断x的值是普通值,还是promise对象
// 如果是普通值,直接调用resolve
// 如果是promise对象,根据promise对象返回的结果,
// 决定调用resolve,还是调用reject
resolvePromise(x, resolve, reject, promise2)
} catch (e) {
reject(e);
}
}, 0)
} else if (this.status === REJECTED) {
failCallBack(this.reason)
} else {
// 等待状态
// 将成功回调和失败回调保存
this.successCallback.push(successCallBack);
this.failCallback.push(failCallBack);
}
});
return promise2;
}
- 之前只关注了then方法中返回成功分支,现在改造一下then方法的返回失败的分支:
then (successCallBack, failCallBack) {
let promise2 = new MyPromise((resolve, reject) => {
// 判断状态
if (this.status === FULFILLED) {
// 这里需要放在setTimeout中,是因为promise2需要等待new MyPromise执行完成后才能得到值
setTimeout(() => {
try {
let x = successCallBack(this.value)
// 判断x的值是普通值,还是promise对象
// 如果是普通值,直接调用resolve
// 如果是promise对象,根据promise对象返回的结果,
// 决定调用resolve,还是调用reject
resolvePromise(x, resolve, reject, promise2)
} catch (e) {
reject(e);
}
}, 0)
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
let x = failCallBack(this.reason)
resolvePromise(x, resolve, reject, promise2)
} catch (e) {
reject(e);
}
}, 0)
} else {
// 等待状态
// 将成功回调和失败回调保存
this.successCallback.push(successCallBack);
this.failCallback.push(failCallBack);
}
});
return promise2;
}
测试代码:
const myPromise = require('./myPromise')
const promise = new myPromise((resolve, reject) => {
// resolve('成功')
// throw new Error('错误')
reject('失败')
})
promise.then(value => {
console.log(value)
}, reason => {
console.log(reason)
return 10000
}).then(value => {
console.log(value)
}, reason => {
console.log(reason.message)
})
结果:
- 这时,then方法中就剩pending状态的代码没有进行错误捕获了,也就是异步代码部分,按照之前的方法进行改造,改造后在resolve和reject中shift后调用时也不需要传参了,所以整体代码如下所示:
const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败
class MyPromise {
constructor(executor) {
try {
executor(this.resolve, this.reject)
} catch (e) {
this.reject(e)
}
}
// promise 状态
status = PENDING;
// 成功之后的值
value = undefined;
// 失败后的原因
reason = undefined;
// 成功回调
successCallback = [];
// 失败回调
failCallback = [];
resolve = value => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return
// 将状态改为成功
this.status = FULFILLED;
// 保存成功之后的值
this.value = value
// 判断成功回调是否存在,如果存在就调用
while (this.successCallback.length) this.successCallback.shift()()
// this.successCallback && this.successCallback(value)
}
reject = reason => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return
// 将状态改为失败
this.status = REJECTED;
// 保存失败后的原因
this.reason = reason
// 判断失败回调是否存在,如果存在就调用
while (this.failCallback.length) this.failCallback.shift()()
// this.failCallback && this.failCallback(reason)
}
then (successCallBack, failCallBack) {
let promise2 = new MyPromise((resolve, reject) => {
// 判断状态
if (this.status === FULFILLED) {
// 这里需要放在setTimeout中,是因为promise2需要等待new MyPromise执行完成后才能得到值
setTimeout(() => {
try {
let x = successCallBack(this.value)
// 判断x的值是普通值,还是promise对象
// 如果是普通值,直接调用resolve
// 如果是promise对象,根据promise对象返回的结果,
// 决定调用resolve,还是调用reject
resolvePromise(x, resolve, reject, promise2)
} catch (e) {
reject(e);
}
}, 0)
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
let x = failCallBack(this.reason)
resolvePromise(x, resolve, reject, promise2)
} catch (e) {
reject(e);
}
}, 0)
} else {
// 等待状态
// 将成功回调和失败回调保存
this.successCallback.push(() => {
setTimeout(() => {
try {
let x = successCallBack(this.value)
resolvePromise(x, resolve, reject, promise2)
} catch (e) {
reject(e);
}
}, 0)
});
this.failCallback.push(() => {
setTimeout(() => {
try {
let x = failCallBack(this.reason)
resolvePromise(x, resolve, reject, promise2)
} catch (e) {
reject(e);
}
}, 0)
});
}
});
return promise2;
}
}
function resolvePromise(x, resolve, reject, promise2) {
if(promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if(x instanceof MyPromise) {
// promise对象
// x.then(value => resolve(value), reason => reject(reason))
// 简化
x.then(resolve, reject)
} else {
// 普通值
resolve(x)
}
}
module.exports = MyPromise;
测试代码:
const myPromise = require('./myPromise')
const promise = new myPromise((resolve, reject) => {
setTimeout(() => {
resolve('成功。。。')
},1000)
})
promise.then(value => {
console.log(value)
return 10000
}, reason => {
console.log(reason)
}).then(value => {
console.log(value)
}, reason => {
console.log(reason)
})
测试结果:
7.then方法的参数变为可选
如下代码所示,应该是向下传递,直到找到回调函数:
const myPromise = require('./myPromise')
const promise = new myPromise((resolve, reject) => {
resolve('成功。。。')
})
promise.then().then().then(value => {
console.log(value)
}, reason => {
console.log(reason)
})
在then方法的开始增加如下代码:
then (successCallBack, failCallBack) {
successCallBack = successCallBack ? successCallBack : value => value
failCallBack = failCallBack ? failCallBack : reason => { throw reason }
......
}
8.Promise.all方法
-
特点
-
接收一个数组,数组中可以传入Promise对象,也可以传入普通值
-
得到结果的顺序一定是传入的顺序
-
返回值也是Promise对象
-
结果都是成功,才返回成功,否则返回失败
-
static all(array) {
let result = [];
// 此处定义index是为了统计array中的方法是否都已经执行完成(例如f1这样的异步方法)
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])
}
}
})
}
- 测试代码:
const myPromise = require('./myPromise')
function p1() {
return new myPromise((resolve, reject) => {
setTimeout(() => {
resolve('p1')
}, 2000)
})
}
function p2() {
return new myPromise((resolve, reject) => {
resolve('p2')
})
}
myPromise.all(['a', 'b', p1(), p2(), 'c']).then(value => {
console.log(value)
})
- 测试结果:
9.promise.resolve方法
-
功能
-
传入普通值,返回包装后Promise对象,方便then调用
-
传入Promise对象,返回原Promise对象
-
-
实现
static resolve (value) {
if (value instanceof MyPromise) {
return value
} else {
return new Promise(resolve => resolve(value))
}
}
- 测试代码
const myPromise = require('./myPromise')
let p2 = new myPromise((resolve, reject) => {
resolve('p2')
})
myPromise.resolve(p2).then(value => console.log(value))
myPromise.resolve(10).then(value => console.log(value))
- 测试结果
10.finally方法
-
功能
-
无论成功与否,finally都会执行
-
可以使用then方法,得到当前Promise对象返回的结果
-
-
实现
finally (callback) {
return this.then(value => {
// 调用resolve静态方法,是为了等待异步调用的完成
return MyPromise.resolve(callback()).then(() => value)
}, reason => {
return MyPromise.resolve(callback()).then(() => {
throw reason;
})
})
}
- 测试代码
const myPromise = require('./myPromise')
function p1() {
return new myPromise((resolve, reject) => {
setTimeout(() => {
resolve('p1')
}, 2000)
})
}
let p2 = new myPromise((resolve, reject) => {
resolve('p2 resolve')
// reject('p2 reject')
})
p2.finally(() => {
console.log('finally')
return p1();
}).then(value => {
console.log(value)
}, reason => {
console.log(reason)
})
- 测试结果:
11.catch方法
-
处理当前Promise的异常方法
-
实现:
catch (failCallback) {
this.then(undefined, failCallback)
}
- 测试代码
const myPromise = require('./myPromise')
let p = new myPromise((resolve, reject) => {
reject('p reject')
})
p.then(value => console.log(value)).catch(reason => console.log(reason))
- 测试结果