如何使用 js 实现一个 Promise.all 方法 PromiseAll All In One
如何使用 js 实现一个 Promise.all 方法 PromiseAll All In One
Promise
Promise.resolve()
Promise.reject()
const promise = new Promise();
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
Promise.all
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
PromiseAll
"use strict";
/**
*
* @author xgqfrms
* @license MIT
* @copyright xgqfrms
* @created 2020-08-0
* @modified
*
* @description
* @difficulty Easy Medium Hard
* @complexity O(n)
* @augments
* @example
* @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
* @solutions
*
*/
const log = console.log;
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 0, 'foo');
});
const promise4 = new Promise((resolve, reject) => {
reject(`promise error`);
});
const promisesOK = [promise1, promise2, promise3];
const promisesError = [promise1, promise2, promise3, promise4];
const OK = Promise.all(promisesOK).then((values) => {
log(`promisesOK values =`, values);
});
const Error = Promise.all(promisesError).then((values) => {
log(`promisesError values =`, values);
}).catch(err => {
log(`error =`, err)
});
setTimeout(() => {
log(`\nOK =`, OK)
log(`Error =`, Error)
}, 5);
/*
$ node promise.all.js
error = promise error
promisesOK values = [ 3, 42, 'foo' ]
OK = Promise { undefined }
Error = Promise { undefined }
*/
原理分析
Promise.resolve, Promise.reject
// Promise,不许需要用 Promise 包裹,但为了对齐也使用 Promise 包裹
promise1 = Promise.resolve(3);
// Promise {<fulfilled>: 3}
// ✅ 未使用 Promise 包裹
promise1.then(v => console.log(v))
// 3
// Promise {<fulfilled>: undefined}
// ✅ 使用 Promise 包裹
Promise.resolve(promise1).then(v => console.log(v))
// 3
// Promise {<fulfilled>: undefined}
// 非 Promise,需要用 Promise 包裹
promise2 = 42;
// 42
// ❌ 未使用 Promise 包裹
promise2.then(v => console.log(v))
// Uncaught TypeError: promise2.then is not a function
// ✅ 使用 Promise 包裹
Promise.resolve(promise2).then(v => console.log(v))
// 42
// Promise {<fulfilled>: undefined}
// 异常 promise
promise4 = new Promise((resolve, reject) => {
reject(`promise error`);
});
// Promise {<rejected>: "promise error"}
// ❌ 未使用 catch 处理
Promise.resolve(promise4).then(v => console.log(v))
// Promise {<rejected>: "promise error"}
// Uncaught (in promise) promise error Promise.then (async)
// ✅ 使用 catch 处理
Promise.resolve(promise4).then(v => console.log(v)).catch(err => console.log(`OK`))
// OK
// Promise {<fulfilled>: undefined}
// Promise.resolve, Promise.reject
solution
PromiseAll
// --unhandled-rejections=strict bug
/*
Unhandled promise rejection.
This error originated either by throwing inside of an async function without a catch block,
or by rejecting a promise which was not handled with .catch().
To terminate the node process on unhandled promise rejection,
use the CLI flag `--unhandled-rejections=strict`,
see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode
*/
"use strict";
/**
*
* @author xgqfrms
* @license MIT
* @copyright xgqfrms
* @created 2020-08-14
* @modified
*
* @description PromiseAll
* @difficulty Easy Medium Hard
* @complexity O(n)
* @augments
* @example
* @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
* @solutions
*
*/
const log = console.log;
const PromiseAll = (promises = []) => {
return new Promise((resolve, reject) => {
let count = 0;
const result = [];
try {
promises.forEach((promise) => {
Promise.resolve(promise).then(value => {
if(value) {
count += 1;
// promise order is not guaranteed / 顺序无法保证 ❌ push
result.push(value)
}
}).catch(err => {
throw new Error(err);
});
});
if(count === promises.length) {
log(`PromiseAll OK`)
return resolve(result)
}
} catch (error) {
log(`Promise Error`, error)
throw new Error(error);
// return reject(error);
}
}).catch(err => {
log(`Promise Error`, err)
return reject(error);
});
}
https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode
"use strict";
/**
*
* @author xgqfrms
* @license MIT
* @copyright xgqfrms
* @created 2020-08-14
* @modified
*
* @description PromiseAll
* @difficulty Easy Medium Hard
* @complexity O(n)
* @augments
* @example
* @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
* @solutions
*
*/
const log = console.log;
const PromiseAll = (promises = []) => {
let count = 0;
const result = [];
return new Promise((resolve, reject) => {
promises.forEach((promise) => {
Promise.resolve(promise).then(value => {
if(value) {
// promise order is guaranteed / 顺序可以保证 ✅ index
result[count] = value;
count += 1;
// result.push(value)
}
// if(result.length === promises.length) {
if(count === promises.length) {
// log(`PromiseAll OK`, promises)
resolve(result)
}
}, err => {
reject(err);
});
});
});
}
// test
const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 0, 'foo');
});
const promise3 = 42;
// const promise2 = 42;
// const promise3 = new Promise((resolve, reject) => {
// setTimeout(resolve, 0, 'foo');
// });
const promise4 = new Promise((resolve, reject) => {
reject(`promise error`);
});
const promisesOK = [promise1, promise2, promise3];
const promisesError = [promise1, promise2, promise3, promise4];
const OK = PromiseAll(promisesOK).then((values) => {
log(`promisesOK values =`, values);
});
// const OK = Promise.all(promisesOK).then((values) => {
// log(`promisesOK values =`, values);
// });
const Error = PromiseAll(promisesError).then((values) => {
log(`promisesError values =`, values);
}).catch(err => {
log(`catch error =`, err)
});
// const Error = Promise.all(promisesError).then((values) => {
// log(`promisesError values =`, values);
// }).catch(err => {
// log(`error =`, err)
// });
setTimeout(() => {
log(`\nOK =`, OK)
log(`Error =`, Error)
}, 5);
/*
$ node promiseAll.js
error = promise error
promisesOK values = [ 3, 42, 'foo' ]
OK = Promise { undefined }
Error = Promise { undefined }
*/
/*
$ node PromiseAll.js ✅
catch error = promise error
promisesOK values = [ 3, 42, 'foo' ]
OK = Promise { undefined }
*/
PromiseAll OK ✅
async promise order OK ✅
"use strict";
/**
*
* @author xgqfrms
* @license MIT
* @copyright xgqfrms
* @created 2020-08-14
* @modified
*
* @description PromiseAll
* @difficulty Easy Medium Hard
* @complexity O(n)
* @augments
* @example
* @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
* @solutions
*
*/
const log = console.log;
const PromiseAll = (promises = [], debug = false) => {
const result = [];
return new Promise((resolve, reject) => {
promises.forEach((promise, i) => {
Promise.resolve(promise).then(value => {
if(value) {
// async promise order OK ✅
result[i] = value;
// async push order bug ❌
// result.push(value)
}
if(result.length === promises.length) {
if(debug) {
log(`PromiseAll OK`, promises)
}
resolve(result)
}
}, err => {
reject(err);
});
});
});
}
// test
const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 0, 'foo');
});
const promise3 = 42;
// const promise2 = 42;
// const promise3 = new Promise((resolve, reject) => {
// setTimeout(resolve, 0, 'foo');
// });
const promise4 = new Promise((resolve, reject) => {
reject(`promise error`);
});
const promisesOK = [promise1, promise2, promise3];
const promisesError = [promise1, promise2, promise3, promise4];
const OK = PromiseAll(promisesOK).then((values) => {
log(`promisesOK values =`, values);
});
// const OK = Promise.all(promisesOK).then((values) => {
// log(`promisesOK values =`, values);
// });
const Error = PromiseAll(promisesError).then((values) => {
log(`promisesError values =`, values);
}).catch(err => {
log(`catch error =`, err)
});
// const Error = Promise.all(promisesError).then((values) => {
// log(`promisesError values =`, values);
// }).catch(err => {
// log(`error =`, err)
// });
setTimeout(() => {
log(`\nOK =`, OK)
log(`Error =`, Error)
}, 5);
/*
$ node PromiseAll.js ✅
catch error = promise error
promisesOK values = [ 3, 'foo', 42 ]
OK = Promise { undefined }
*/
/*
$ node promise.all.js
error = promise error
promisesOK values = [ 3, 'foo', 42 ]
OK = Promise { undefined }
Error = Promise { undefined }
*/
refs
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
(🐞 反爬虫测试!打击盗版⚠️)如果你看到这个信息, 说明这是一篇剽窃的文章,请访问 https://www.cnblogs.com/xgqfrms/ 查看原创文章!
©xgqfrms 2012-2021
www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!
原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!
本文首发于博客园,作者:xgqfrms,原文链接:https://www.cnblogs.com/xgqfrms/p/13503592.html
未经授权禁止转载,违者必究!