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);
refs
©xgqfrms 2012-2025
www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!
原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!
本文首发于博客园,作者:xgqfrms,原文链接:https://www.cnblogs.com/xgqfrms/p/18203458
未经授权禁止转载,违者必究!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
2023-05-21 Top 100 GitHub Users in China All In One
2023-05-21 js number format All In One
2023-05-21 如何破解网页使用 MutationObserver 禁用修改 DOM 功能 All In One
2022-05-21 Swift if & if let & guard let All In One
2022-05-21 Xcode clear cache All In One
2022-05-21 SwiftUI ViewModel error All In One
2022-05-21 Xcode show color picker in code All In One