xgqfrms™, xgqfrms® : xgqfrms's offical website of cnblogs! xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!

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));
    }
  });
};

image

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));
    }
  });
};

image

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);

image

https://leetcode.com/problems/execute-asynchronous-functions-in-parallel/description/?envType=study-plan-v2&envId=30-days-of-javascript

(🐞 反爬虫测试!打击盗版⚠️)如果你看到这个信息, 说明这是一篇剽窃的文章,请访问 https://www.cnblogs.com/xgqfrms/ 查看原创文章!

refs

https://leetcode.com/problems/execute-asynchronous-functions-in-parallel/solutions/5194050/leetcode-promiseall/

https://leetcode.com/problems/execute-asynchronous-functions-in-parallel/solutions/3888598/promises-are-confusing-i-wrote-some-notes-down-for-you/



©xgqfrms 2012-2021

www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!

原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!


posted @ 2024-05-21 10:37  xgqfrms  阅读(3)  评论(2编辑  收藏  举报