返回

Promise 常见题目剖析:揭开异步编程的奥秘

前端

1. Promise 对象池:统筹管理异步任务

题目:

编写一个异步函数 promisePool,它接收一个异步函数数组 functions 和 池限制 n。它应该返回一个 promise 对象,当所有输入函数都执行完毕时,它应该被解析,并且结果应该是一个包含所有异步函数返回值的数组。如果其中任何一个函数抛出错误,promisePool 也应该被拒绝,并且错误应该被传递。

解答:

const promisePool = (functions, n) => {
  return new Promise(async (resolve, reject) => {
    let completed = 0;
    let results = [];
    const errors = [];

    const run = () => {
      while (completed < functions.length && functionsQueue.length < n) {
        const func = functions.shift();
        functionsQueue.push(func);

        func()
          .then((result) => {
            completed++;
            functionsQueue.pop();
            results.push(result);
            run();
          })
          .catch((error) => {
            errors.push(error);
            reject(errors);
          });
      }

      if (completed === functions.length && errors.length === 0) {
        resolve(results);
      }
    };

    run();
  });
};

2. Promise 并行执行:提升代码运行效率

题目:

编写一个函数,它接收一个包含异步函数的数组,然后并行执行这些函数,并返回一个 promise 对象,当所有函数都执行完毕时,它应该被解析,并且结果应该是一个包含所有异步函数返回值的数组。

解答:

const parallel = (functions) => {
  return Promise.all(functions.map((func) => func()));
};

3. Promise 串行执行:确保任务顺序执行

题目:

编写一个函数,它接收一个包含异步函数的数组,然后串行执行这些函数,并返回一个 promise 对象,当所有函数都执行完毕时,它应该被解析,并且结果应该是一个包含所有异步函数返回值的数组。

解答:

const serial = (functions) => {
  return functions.reduce((promiseChain, func) => {
    return promiseChain.then(() => func());
  }, Promise.resolve());
};

4. Promise 超时处理:防止异步任务无限等待

题目:

编写一个函数,它接收一个异步函数和一个超时时间,然后执行该异步函数,并在超时时间内返回一个 promise 对象。如果异步函数在超时时间内执行完毕,则 promise 对象应该被解析,并且结果应该是异步函数的返回值。如果异步函数在超时时间内没有执行完毕,则 promise 对象应该被拒绝,并且错误应该是超时错误。

解答:

const withTimeout = (fn, timeout) => {
  return new Promise((resolve, reject) => {
    const timer = setTimeout(() => {
      reject(new Error('Timeout'));
    }, timeout);

    fn().then((result) => {
      clearTimeout(timer);
      resolve(result);
    }).catch((error) => {
      clearTimeout(timer);
      reject(error);
    });
  });
};

结语

通过对 Promise 常见题目的剖析,您对 Promise 的理解无疑会更上一层楼。掌握了这些技巧,您将能够轻松应对异步编程的挑战,编写出更加健壮、高效的代码。