Promise是更优雅的实现异步编程的方法(避免了层层嵌套回调)。
Promise对象有两种结果状态:
- resolved:表示异步操作执行成功了
- rejected:表示异步操作执行失败了
状态只受异步操作的影响,与其他无关,并且状态一旦确定则无法改变。
Promise简单使用:
const promise = new Promise((resolve, reject) => {
let condition = false;
if (condition) {
resolve('promise ok');
} else {
reject(new Error('promise error'));
}
});
promise.then((val) => {
console.log('promise resolve', val);
}, (err) => {
console.log('promise reject', err);
})
// promise reject Error: promise error
复制代码
- resolve:在异步操作成功时(resolved状态)调用
- reject:在异步操作失败时(rejected状态)调用
then方法
- 第一个函数参数对应为resolve的执行。
- 第二个函数参数对应为rejecte的执行。
其中回调中如果有return,则返回的是一个新的promise实例,因此可通过链式写法调用新promise实例的then方法。如:
promise.then((val) => {
console.log('promise resolve', val);
return 'val ok';
}).then((val) => {
console.log('promise resolve2', val);
})
// promise resolve promise ok
// promise resolve2 val ok
复制代码
catch方法
可用于指定发生错误时的回调函数:
- 当异步操作结果变为rejected状态
- then方法指定的回调函数抛出错误
由于catch可捕获以上两种错误,因此推荐写法:
promise.then((val) => {
console.log('promise resolve', val);
}).catch((err) => {
console.log('promise reject', err);
})
// promise reject Error: promise error
复制代码
如果catch中抛出一个错误,仍可以被后面的catch方法所捕获。如:
promise.then((val) => {
console.log('promise resolve', val);
}).catch((err) => {
console.log('catch1 error', err);
throw new Error('catch error');
}).catch((err) => {
console.log('catch2 error:', err);
})
// catch1 error Error: promise error
// catch2 error: Error: catch error
复制代码
Promise内如果出现错误,但没有定义错误的回调函数,则不会影响外部的脚本执行。如:
promise.then((val) => {
console.log('promise resolve', val);
})
console.log('continue');
// continue
复制代码
finally方法
不论promise对象最后状态如何,都会执行此操作。(回调函数中不接受参数,其本质是then方法的特例)。如:
const promise = new Promise((resolve, reject) => {
resolve();
});
promise.then(() => {
console.log('promise ok');
throw new Error('then error');
}).catch((err) => {
console.log('catch', err);
}).finally(() => {
console.log('finally');
});
// promise ok
// catch Error: then error
// finally
复制代码
Promise.all()
接收一个由若干promise对象组成的数组作为参数。 当所有promise对象的状态都变成resolved则整体状态置为resolved,否则整体状态为rejected。如:
const promise1 = new Promise((resolve, reject) => {
resolve('promise1 ok');
});
const promise2 = new Promise((resolve, reject) => {
throw new Error('promise2 error')
});
Promise.all([promise1, promise2]).then(() => {
console.log('all promises ok');
}).catch((err) => {
console.log('some promise error', err);
});
// some promise error Error: promise2 error
复制代码
但当promise2定义了catch去捕获error时,代表promise2的最终状态会变为resolved,则promise.all执行then方法的回调。如:
const promise1 = new Promise((resolve, reject) => {
resolve('promise1 ok');
}).then(() => {
console.log('promise1 ok');
}).catch((err) => {
console.log('promise1 err', err);
});
const promise2 = new Promise((resolve, reject) => {
throw new Error('promise2 error')
}).then(() => {
console.log('promise2 ok');
}).catch((err) => {
console.log('promise2 err', err);
});
Promise.all([promise1, promise2]).then(() => {
console.log('all promises ok');
}).catch((err) => {
console.log('some promise error', err);
});
// promise1 ok
// promise2 err Error: promise2 error
// all promises ok
复制代码
Promise.race()
类似于Promise.all(),区别是当第一个promise更新状态后整体则更新状态,并且状态同第一个promise保持一致(与其他promise无关)。如:
const promise1 = new Promise((resolve, reject) => {
resolve('promise1 ok');
});
const promise2 = new Promise((resolve, reject) => {
throw new Error('promise2 error');
});
Promise.race([promise1, promise2]).then(() => {
console.log('first promise ok');
}).catch((err) => {
console.log('first promise error', err);
});
// first promise ok
复制代码