JavaScript execute asynchronous functions in Parallel with count and Promise All In One
JavaScript execute asynchronous functions in Parallel with count and Promise All In One
JavaScript 使用 count 和 Promise
并行
执行异步函数
errors
function promiseAll<T>(functions: Fn<T>[]): Promise<T[]> {
return new Promise((resolve, reject) => {
let temp = [];
for(let [i, func] of Object.entries(functions)) {
console.log(`✅ i =`, i);
console.log(`✅ func =`, func);
(async (index) => {
await func().then(value => {
temp[index] = value;
console.log(`❓ index =`, index);
console.log(`value =`, value);
console.log(`temp =`, temp);
if(temp.length === functions.length) {
return resolve(temp);
}
// temp = (3) [4, empty, 16] ❌
// if(temp.length === functions.length && !temp.some(v => Object.prototype.toString.call(v) === '[object Promise]')) {
// return resolve(temp);
// }
}).catch(err => {
return reject(err);
});
})(i);
}
});
};
function promiseAll<T>(functions: Fn<T>[]): Promise<T[]> {
return new Promise((resolve, reject) => {
let temp = [];
let index = 0;
for(let [i, func] of Object.entries(functions)) {
console.log(`✅ i =`, i);
// console.log(`func =`, func);
func().then(value => {
// temp[i] = value;
temp[index] = value;
index += 1;
// temp.push(value);
console.log(`❓ i =`, i);
// index 0 twice bug ❌ 覆盖 bug
// 💩 temp = [ 4, <1 empty item>, 16 ]
console.log(`value =`, value);
console.log(`temp =`, temp);
// value = 16
// temp = [ 4, <1 empty item>, 16 ] 2
// setTimeout 时间先后顺序 bug ❌
if(temp.length === functions.length && !temp.some(v => Object.prototype.toString.call(v) === '[object Promise]')) {
return resolve(temp);
}
// setTimeout 时间先后顺序 bug ❌
// setTimeout(() => {
// if(temp.length === functions.length) {
// return resolve(temp);
// }
// }, 0);
}).then(() => {
// setTimeout 时间先后顺序 bug ❌
// console.log(`temp =`, temp);
// if(temp.length === functions.length) {
// return resolve(temp);
// }
}).catch(err => {
return reject(err);
}).finally(() => {
// setTimeout 时间先后顺序 bug ❌
// console.log(`temp =`, temp);
// if(temp.length === functions.length) {
// return resolve(temp);
// }
});
// if(temp.length === functions.length) {
// return resolve(temp);
// }
// let id = setInterval(() => {
// if(temp.length === functions.length && !temp.some(v => Object.prototype.toString.call(v) === '[object Promise]')) {
// clearInterval(id);
// return resolve(temp);
// }
// }, 0);
}
});
};
function promiseAll() {
return new Promise((resolve, reject) => {
let temp = [];
for(let [i, func] of Object.entries(functions)) {
// console.log(`i =`, i);
// console.log(`func =`, func);
func().then(value => {
console.log(`value =`, value);
temp[i] = value;
console.log(`temp =`, temp, i);
}).catch(err => {
return reject(err);
});
}
// ❌ bug
console.log(`temp ? =`, temp);
setTimeout(() => {
console.log(`temp =`, temp);
if(temp.length === functions.length) {
return resolve(temp);
}
}, 0);
});
};
问题剖析
type Fn<T> = () => Promise<T>
function promiseAll<T>(functions: Fn<T>[]): Promise<T[]> {
return new Promise((resolve, reject) => {
let temp = [];
let count = 0;
for(let [i, func] of Object.entries(functions)) {
func().then(value => {
temp[i] = value;
count += 1;
// count ✅
// if(count === functions.length) {
// return resolve(temp);
// }
// bug ❌
// 使用 temp[i] = promise 赋值的时候 temp 长度就具有了;
// 但是此时 promise 可能还没有返回结果,从而导致出现 empty 值的bug
// temp = (3) [4, empty, 16] ❌
// i = 2 时候,temp 长度为 3, 但是此时 temp[1] 的 setTimeout 还没有返回结果,故出现 empty bug ❌
if(temp.length === functions.length) {
return resolve(temp);
}
}).catch(err => reject(err));
}
});
};
solutions
type Fn<T> = () => Promise<T>
function promiseAll<T>(functions: Fn<T>[]): Promise<T[]> {
return new Promise((resolve, reject) => {
let temp = [];
let count = 0;
for(let [i, func] of Object.entries(functions)) {
func().then(value => {
temp[i] = value;
count += 1;
// count ✅
// 使用 count 避免出现 empty 返回值情况 ✅
if(count === functions.length) {
return resolve(temp);
}
}).catch(err => reject(err));
}
});
};
demos
LeetCode 2721. Execute Asynchronous Functions in Parallel
function promiseAll() {
return new Promise((resolve, reject) => {
let temp = [];
let count = 0;
for(let [i, func] of Object.entries(functions)) {
func().then(value => {
temp[i] = value;
count += 1;
// count ✅
// 使用 count 避免出现 empty 返回值情况 ✅
if(count === functions.length) {
return resolve(temp);
}
}).catch(err => reject(err));
}
});
};
const functions = [() => new Promise(resolve => setTimeout(() => resolve(4), 50)), () => new Promise(resolve => setTimeout(() => resolve(10), 150)), () => new Promise(resolve => setTimeout(() => resolve(16), 100))];
promiseAll(functions).then(console.log);
(🐞 反爬虫测试!打击盗版⚠️)如果你看到这个信息, 说明这是一篇剽窃的文章,请访问 https://www.cnblogs.com/xgqfrms/ 查看原创文章!
refs
©xgqfrms 2012-2021
www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!
原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!
本文首发于博客园,作者:xgqfrms,原文链接:https://www.cnblogs.com/xgqfrms/p/18203458
未经授权禁止转载,违者必究!