一、Promise概述
Promise是一种用于处理异步操作的技术,它是一种异步计算的抽象,简单来说就是实现异步编程的重要手段。Promise可以让我们在代码内部预先定义好异步操作成功后的结果值、失败后的处理逻辑和如何响应异步操作结果的状态。
以下是Promise的基本用法:
const promise = new Promise(function(resolve, reject) {
// 在这里执行异步操作
// 成功时调用resolve,失败时调用reject
});
promise.then(function(successResult) {
// 对于成功的处理逻辑
}).catch(function(errorResult) {
// 对于失败的处理逻辑
});
首先我们创建了一个Promise实例,其中包含了resolve和reject两个参数,在异步操作成功时调用resolve,并传递异步计算的结果给到then方法继续处理。在异步操作抛出错误时,我们调用reject,并将错误信息传给catch方法进行错误处理。
二、Promise状态
Promise有3种状态:
- pending – 未完成状态,这时候既不是成功也不是失败。
- fulfilled – 成功状态,表示异步操作已经完成。
- rejected – 失败状态,表示异步操作已经失败。
在Promise实例创建时,状态为pending。当调用resolve时,状态变为fulfilled;调用reject时,状态变为rejected。Promise状态一旦确定就不能再次改变。
以下是实现Promise状态的例子:
let myPromise = new Promise((resolve, reject) => {
let isSuccess = true; // 异步操作是否成功
if (isSuccess) {
resolve("异步操作成功了!");
} else {
reject("异步操作失败了!");
}
});
myPromise.then((result) => {
console.log(result);
}, (error) => {
console.log(error);
});
上述代码中,当异步操作成功时,我们调用了resolve并传递了一个成功的结果给到then。在异步操作失败时,我们调用了reject并传递了错误信息到catch方法。
三、 Promise API
1. Promise.all()
Promise.all接收一个Promise对象数组作为参数,当所有Promise对象完成时,它会返回一个由每个Promise结果值组成的数组。如果有任何一个Promise对象失败,它 immediately 也会失败,随后的 then 方法不会执行,而是进入 catch。
以下是Promise.all的例子:
let promisesList = [Promise.resolve(3), Promise.resolve(4), new Promise((resolve, reject) => {
setTimeout(function () {
resolve('done');
}, 1000);
})];
Promise.all(promisesList).then(function (results) {
console.log(results);
}).catch(function (error) {
console.error(error);
});
当promisesList中所有的Promise对象完成时,则会打印值为3,4,和’done’的数组results。
2. Promise.race()
Promise.race接受一组Promise对象作为参数,并返回第一个完成后的Promise对象的结果,不管它是成功还是失败。如果传入一个空数组,Promise.race 将永远处于等待状态。
以下是Promise.race的例子:
let p1 = new Promise(function(resolve, reject) {
setTimeout(resolve, 500, "p1");
});
let p2 = new Promise(function(resolve, reject) {
setTimeout(resolve, 200, "p2");
});
Promise.race([p1, p2]).then(function(value) {
console.log(value);
// 在p2成功之后就立即完成
});
当p2成功时立即完成该Promise,返回值为’p2’。
3. Promise.reject()
Promise.reject是一个标准的Promise reject状态函数,它返回一个带有拒绝原因参数的Promise对象。
Promise.reject("Something went wrong").catch((reason) => {
console.log('Handle rejected promise ('+reason+') here.');
});
在使用Promise.reject时,我们将一个错误的消息传递给了catch方法,以便我们能够及时处理Promise对象的拒绝状态。
4. Promise.resolve()
Promise.resolve是一个标准的Promise resolved状态函数,它返回一个解决的Promise对象。
Promise.resolve(4).then((result) => {
console.log(result + 5); // 输出 9
});
在上述代码中,我们将数字4传递给了Promise.resolve,当Promise对象解决时,输出值为9。
四、Promise并行与串行
1. Promise并行
假设我们有多个异步任务需要同时进行,完成这些异步任务的最终结果是我们需要的。这时候可以使用Promise.all方法,根据Promise的规范,只有在所有Promise都同意完成后,Promise.all才会返回复合Promise中所有成功完成操作的结果的一个Promise。
以下是Promise并行的例子:
// 模拟异步任务
function task(num) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(num);
}, Math.random() * 3000);
});
}
// 多个异步任务同时进行
Promise.all([task(1), task(2), task(3)]).then(function(results) {
console.log(results); // [1,2,3]
}).catch(function(err) {
console.error(err);
});
在上述代码中,我们使用Promise.all方法来实现多个异步任务的同时进行,当这些异步任务全部完成后,我们才会执行then方法,输出每个任务的结果值。
2. Promise串行
当需要让多个异步任务依次顺序执行时,可以使用Promise.then方法。这种方式也称为链式调用。
以下是Promise串行的例子:
// 模拟异步任务
function task(num) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(num);
}, Math.random() * 3000);
});
}
task(1)
.then(function(result) {
console.log(result);
return task(2);
})
.then(function(result) {
console.log(result);
return task(3);
})
.then(function(result) {
console.log(result);
})
.catch(function(err) {
console.error(err);
});
在上述代码中,我们使用Promise.then方法来实现异步任务的顺序执行,每一个任务都必须在上一个任务完成后才能执行。使用then方法将任务分别串联起来,并输出每一个结果值。
五、Promise优缺点
1. Promise优点
- 解决了回调地狱问题
- 更易于代码维护和阅读
- 提供了处理异步操作更好的方式
2. Promise缺点
- 无法取消Promise
- 在适用的情况下,速度比传统回调慢,具有更多的内存消耗
- Promise 在处理硬盘异步IO(文件系统)时存在问题
六、结论
Promise是Javascript中异步编程的重要手段,通过引入Promise规范,我们可以更好地处理异步操作,避免回调地狱等问题;同时也提供了多种优化性能和提高可读性的API。
不过Promise也有一些缺点,在使用过程中需要仔细斟酌,根据实际情况选择是否使用。
原创文章,作者:JMYMW,如若转载,请注明出处:https://www.506064.com/n/332944.html