Promise.all 实现之我见
2023-12-24 09:40:52
前言:JavaScript的异步编程
JavaScript是一种单线程语言,这意味着它一次只能执行一个任务。但是,JavaScript提供了异步编程的机制,允许我们同时执行多个任务。异步编程是通过事件循环实现的,事件循环是一个不断循环的过程,它检查是否有待处理的任务,如果有,就执行它们。
在JavaScript中,有两种常用的异步编程方式:回调函数和Promise对象。回调函数是一种将函数作为参数传递给另一个函数的方式,当另一个函数执行完毕后,它会调用回调函数。Promise对象则是一种表示异步操作的结果的对象,它可以处于三种状态之一:pending(等待)、fulfilled(已完成)和rejected(已拒绝)。
Promise.all:等待所有Promise
Promise.all方法可以等待多个Promise同时完成,并返回一个包含所有Promise结果的新Promise。如果所有Promise都成功完成,新Promise的状态将变为fulfilled,并将所有Promise的结果作为参数传递给它的回调函数。如果任何一个Promise被拒绝,新Promise的状态将变为rejected,并将第一个被拒绝的Promise的错误作为参数传递给它的回调函数。
实现Promise.all
下面我们将一步一步实现Promise.all方法。首先,我们需要创建一个新的Promise实例。
function promiseAll(promises) {
return new Promise((resolve, reject) => {
// ...
});
}
接下来,我们需要遍历传入的promises数组,并为每个Promise添加一个监听器。监听器会检查Promise的状态,如果Promise成功完成,则将结果存储到一个数组中,如果Promise被拒绝,则直接调用reject函数,并将错误作为参数传递给它。
function promiseAll(promises) {
return new Promise((resolve, reject) => {
const results = [];
promises.forEach((promise) => {
promise.then(
(result) => {
results.push(result);
if (results.length === promises.length) {
resolve(results);
}
},
(error) => {
reject(error);
}
);
});
});
}
最后,我们需要检查promises数组中是否还有未完成的Promise,如果没有,则调用resolve函数,并将results数组作为参数传递给它。
function promiseAll(promises) {
return new Promise((resolve, reject) => {
const results = [];
promises.forEach((promise) => {
promise.then(
(result) => {
results.push(result);
if (results.length === promises.length) {
resolve(results);
}
},
(error) => {
reject(error);
}
);
});
// 检查是否还有未完成的Promise
if (results.length === promises.length) {
resolve(results);
}
});
}
现在,我们已经实现了Promise.all方法。我们可以使用它来等待多个Promise同时完成,并获取所有Promise的结果。
使用Promise.all
我们可以使用Promise.all方法来实现各种各样的异步操作。例如,我们可以使用它来加载多个资源,或者并发执行多个任务。
// 加载多个资源
const images = [
'image1.jpg',
'image2.jpg',
'image3.jpg',
];
Promise.all(images.map((image) => {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => {
resolve(img);
};
img.onerror = () => {
reject(new Error('Failed to load image'));
};
img.src = image;
});
})).then((images) => {
// 所有图片已加载完成
console.log(images);
});
// 并发执行多个任务
const tasks = [
() => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Task 1 completed');
}, 1000);
});
},
() => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Task 2 completed');
}, 2000);
});
},
() => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Task 3 completed');
}, 3000);
});
},
];
Promise.all(tasks()).then((results) => {
// 所有任务已完成
console.log(results);
});
结语
Promise.all方法是JavaScript中一个非常有用的工具,它可以帮助我们等待多个Promise同时完成,并获取所有Promise的结果。我们在本文中实现了Promise.all方法,并探讨了它在实际场景中的应用。希望本文能够帮助你对Promise.all方法有更深入的理解和认识。