1. 是什么
Promise是一种异步编程的解决方案,用于处理异步操作并返回结果。
主要作用是解决回调函数嵌套(回调地狱)的问题,使异步操作更加清晰、易于理解和维护。
2. 怎么用
Promise有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。当一个Promise被创建时,它的状态为pending。当异步操作完成并成功时,Promise的状态会变为fulfilled,并返回一个结果。当异步操作失败时,Promise的状态会变为rejected,并返回一个错误信息。
基本语法
// 创建一个promise
let promise = new Promise(function(resolve, reject) {// 异步操作if (异步操作成功) {resolve(value); // 将异步操作的结果传递给Promise对象,状态变为fulfilled} else {reject(error); // 将异步操作的错误信息传递给Promise对象,状态变为rejected}
});promise.then(function(result) {// 异步操作成功时的处理代码
}).catch(function(error) {// 异步操作失败时的处理代码
});
常用方法
1.then
then中一般传入两个参数(函数),第一个对应resolve成功的回调,第二个对应reject失败的回调,如下
function onResolved(res) {
console.log("resolved-" + res); // resolved-成功了
}
function onRejected(err) {
console.log("rejected-" + err); // rejected-失败了
}
new Promise((resolve, reject) => {
resolve('成功了');// reject('失败了')
}).then(onResolved, onRejected);
then的第二个参数就等同于catch方法,但是需要注意
- Promise内部报错,reject抛出错误后,then的第二个参数和catch方法都存在的情况下,只有then的第二个参数能捕获到,如果then的第二个参数不存在,catch方法会捕捉到
- catch不仅捕捉promise中抛出的错误,还会捕捉前面then中的错误
2.catch
捕捉promise错误函数,和then的第二个参数(函数)作用一样,处理错误,由于Promise抛出错误具有冒泡性质,能够不断传递,会传到catch中,所以一般来说所有错误处理放在catch中,then中只处理成功的,同时catch还会捕捉then中第一个参数(函数)抛出的异常
new Promise((resolve, reject) => {
reject();
}).catch((err)=> {
console.log(err)
});
3.finally
- finally 方法没有参数,也不会改变 Promise 的状态,它只是在 Promise 结束时提供了一个通知机制,让我们可以在 Promise 结束后执行一些清理工作(比如操作文件的时候关闭文件流)。
- Promise对象的finally()方法用于在Promise成功或拒绝时使用
- 不管promise最后的状态,在执行完then或catch指定的回调函数以后,都会执行finally方法指定的回调函数,它可以防止Promise的then()和catch()方法中的代码重复。
// 栗子1
function onFinally() {
console.log('结束');
}
new Promise((resolve, reject) => {}).finally(onFinally);
// 栗子2
let promise = new Promise((resolve,reject) => {
resolve('resolve')
})
promise.then((res) => {
console.log(res)
}).catch((err) => {
console.log(err)
}).finally(()=> {
console.log('this finally')
})
// resolve
// this finally
4.all
接受一个具有Iterable接口的类型,如数组,Map,Set,传入多个promise,
每一个promise执行成功resolve,最后才执行成功(返回一个Promise实例),进入then,否则失败进入catch
function p1() {
var promise1 = new Promise(function (resolve, reject) {
console.log("p1的第一条输出语句");
resolve("p1完成");
});
return promise1;
}
function p2() {
var promise2 = new Promise(function (resolve, reject) {
console.log("p2的第一条输出语句");
setTimeout(() => {
console.log("p2的第二条输出语句");
resolve("p2完成");}, 2000);
});
return promise2;
}
}
function p3() {
var promise3 = new Promise(function (resolve, reject) {
console.log("p3的第一条输出语句");
resolve("p3完成");
});
return promise3;
}
Promise.all([p1(), p2(), p3()]).then(function (data) {
console.log(data);
});// 输出
// p1的第一条输出语句;
// p2的第一条输出语句;
// p3的第一条输出语句;
// p2的第二条输出语句[("p1完成", "p2完成", "p3完成")];
var p1 = new Promise((resolve, reject) => {
setTimeout(resolve, 1000, 'one');
});
var p2 = new Promise((resolve, reject) => {
setTimeout(resolve, 2000, 'two');
});
var p3 = new Promise((resolve, reject) => {
setTimeout(resolve, 3000, 'three');
});
var p4 = new Promise((resolve, reject) => {
setTimeout(resolve, 4000, 'four');
});
var p5 = new Promise((resolve, reject) => {
reject('reject');// setTimeout(resolve, 5000, 'five');
});
Promise.all([p1, p2, p3, p4, p5]).then(values => {
console.log(values); // [ 'one', 'two', 'three', 'four', 'five' ]
}, reason => {
console.log(reason) // reject
});
5.allSettled
接受一个具有Iterable接口的类型,如数组,Map,Set,传入多个promise,
每个promise状态改变成fulfilled或者rejected之后返回,返回的是一个数组对象,对象中有状态status和每一项的返回结果value
Promise.allSettled([p1, p2, p3, p4, p5]).then(values => {
console.log(values);
}, reason => {console.log(reason)
});
// [
// { status: 'fulfilled', value: 'one' },
// { status: 'fulfilled', value: 'two' },
// { status: 'fulfilled', value: 'three' },
// { status: 'fulfilled', value: 'four' },
// { status: 'rejected', reason: 'reject' }
// ]
6.race
以快为准,数组中所有的promise对象,有一个先执行了何种状态,该对象就为何种状态,并执行相应函数
接受一个具有Iterable接口的类型,如数组,Map,Set,传入多个promise,
其中有一个promise返回了,不管是fulfilled或者rejected,直接返回这个promise的结果
function p1() {
var promise1 = new Promise(function (resolve, reject) {
console.log("p1的第一条输出语句");
resolve("p1完成");
});
return promise1;
}
function p2() {
var promise2 = new Promise(function (resolve, reject) {
console.log("p2的第一条输出语句");
setTimeout(() => {
console.log("p2的第二条输出语句");
resolve("p2完成");
}, 2000);
});
return promise2;
}
function p3() {
var promise3 = new Promise(function (resolve, reject) {
console.log("p3的第一条输出语句");
resolve("p3完成");
});
return promise3;
}
Promise.race([p1(), p2(), p3()]).then(function (data) {
console.log(data);
});// 输出
// p1的第一条输出语句
// p2的第一条输出语句
// p3的第一条输出语句
// p1完成
7.any
接受一个具有Iterable接口的类型,如数组,Map,Set,传入多个promise,
当传入的任何一个promise成功的时候,不管其他是否成功或者失败,会把成功的那个promise返回
如果传入的是一个空的数组(Map,Set),返回一个已失败状态的promise,如下
注意
Promise的以上方法都属于 微任务。当Promise状态变为已解决(resolved)或被拒绝(rejected)时,这些方法会产生微任务。这些微任务会在主线程空闲时按照顺序依次执行。
3. 有什么问题
- 首先,无法取消 Promise,一旦新建它就会立即执行,无法中途取消。
- 其次,如果不设置回调函数,Promise 内部抛出的错误,不会反应到外部。
- 第三,当处于 Pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。