Skip to content

Instantly share code, notes, and snippets.

@Teemwu
Last active September 15, 2021 07:40
Show Gist options
  • Save Teemwu/904bea9369decf3649ba86f63993bbab to your computer and use it in GitHub Desktop.
Save Teemwu/904bea9369decf3649ba86f63993bbab to your computer and use it in GitHub Desktop.
手写 Promise.all 和 Promise.race
'use strict';
/**
* 手写实现 Promise.all 方法
* @param {string|array} values 一个可迭代对象
* @returns promise
*/
Promise._all = (values) => {
// 判断是否为可迭代对象
if (!values.hasOwnProperty('length')) {
throw new Error(`TypeError: ${typeof values} is not iterable`);
}
// 返回 promise
return new Promise((resolve, reject) => {
const len = values.length;
// 传入空数组时直接返回
if (!len) return resolve(values);
let counter = 0;
const resolved = new Array(len);
// 遍历传入可迭代对象
for (const val of values) {
// 使用 Promise.resolve 将传入值包一层
Promise.resolve(val).then((res) => {
// 获取 promise 值,保存到 resolved
resolved[counter] = res;
counter++;
// 获取到所有值, 返回最终结果
if (counter === len) resolve(resolved);
}, reject);
}
})
}
const p1 = Promise.resolve(3);
const p2 = 123;
const p3 = new Promise((resolve, reject) => setTimeout(resolve, 100, 'foo'));
// const p4 = Promise.reject('reject msg');
const p5 = [];
const p6 = 'str';
// Promise._all(p1).then(console.log); // TypeError: object is not iterable 
// Promise._all(p2).then(console.log); // TypeError: number is not iterable 
Promise._all([p1, p2, p3]).then(console.log);
// Promise._all([p1, p2, p3, p4]).then(console.log); // reject msg
Promise._all(p5).then(console.log); // []
Promise._all(p6).then(console.log); // [ 's', 't', 'r' ]
'use strict';
/**
* 手写实现 Promise.race 方法
* @param {string|array} values 一个可迭代对象
* @returns promise
*/
Promise._race = (values) => {
// 判断是否为可迭代对象
if (!values.hasOwnProperty('length')) {
throw new Error(`TypeError: ${typeof values} is not iterable`);
}
// 返回 promise
return new Promise((resolve, reject) => {
// 遍历传入可迭代对象
for (const val of values) {
// 使用 Promise.resolve 将传入值包一层
Promise.resolve(val).then(resolve, reject);
}
})
}
const p3 = new Promise((resolve, reject) => setTimeout(resolve, 200, 'foo'));
const p4 = new Promise((resolve, reject) => setTimeout(resolve, 100, 'foo1'));
Promise._race([p4, p3]).then(console.log); // foo1
Promise._race([]).then(console.log); // 无返回:Promise {<pending>}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment