深入理解Promise的九大方法

前言

JavaScript中的Promise对象为异步编程提供了一种优雅的解决方案。在Promise中,有许多方法可以帮助我们处理异步操作,包括解决、拒绝、链式调用等。本文将介绍JavaScript中常见的Promise方法,包括 Promise.resolvePromise.rejectPromise.thenPromise.catchPromise.finallyPromise.allPromise.allSettledPromise.race以及Promise.any,并提供相关示例代码以加深理解。

1. Promise.resolve

Promise.resolve()方法用于将一个值或另一个Promise对象转换为Promise对象。如果传入的是一个 Promise,则返回该Promise;如果传入的是一个普通值,则返回一个状态为resolvedPromise对象,并以该值作为结果。

示例代码:

ini 复制代码
const resolvedPromise = Promise.resolve(42);
resolvedPromise.then(value => {
  console.log(value); // 输出: 42
});

2. Promise.reject

Promise.reject()方法用于创建一个状态为rejectedPromise对象,并将指定的错误作为拒绝原因。

示例代码:

vbnet 复制代码
const rejectedPromise = Promise.reject(new Error('Promise reject error'));
rejectedPromise.catch(error => {
  console.error(error.message); // 输出: Promise reject error
});

3. Promise.then

Promise.then()方法用于指定在当前Promise状态改变时的回调函数。它接受两个参数:onFulfilledonRejected,分别对应状态变为resolvedrejected时的回调函数。此外,Promise.then()方法返回一个新的Promise对象。

示例代码:

ini 复制代码
const promise = new Promise(resolve => {
  setTimeout(() => {
    resolve(42);
  }, 1000);
});

promise.then(value => {
  console.log(value); // 输出: 42
});

4. Promise.catch

Promise.catch()方法用于指定在Promise链中任何位置发生错误时的回调函数。它是 Promise.then(undefined, onRejected)方法的简便写法。

示例代码:

javascript 复制代码
const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject(new Error('Promise rejected'));
  }, 1000);
});

promise.catch(error => {
  console.error(error.message); // 输出: Promise rejected
});

5. Promise.finally

Promise.finally()方法用于指定在Promise链中不论状态如何都必须执行的回调函数。它返回一个Promise,在finally回调函数执行完毕后,Promise的状态不会发生变化。

示例代码:

javascript 复制代码
const promise = new Promise(resolve => {
  setTimeout(() => {
    resolve(42);
  }, 1000);
});

promise.finally(() => {
  console.log('Finally block executed');
});

6. Promise.all - 手写实现和应用

Promise.all()方法接受一个可迭代的对象作为参数,当所有Promise都已解决或有一个Promise被拒绝时,返回一个新的Promise

手写实现代码:

ini 复制代码
function customAll(promises) {
  return new Promise((resolve, reject) => {
    const results = [];
    let completedPromises = 0;

    promises.forEach((promise, index) => {
      Promise.resolve(promise)
        .then(value => {
          results[index] = value;
          completedPromises++;

          if (completedPromises === promises.length) {
            resolve(results);
          }
        })
        .catch(error => {
          reject(error);
        });
    });
  });
}

示例代码:

ini 复制代码
const promise1 = Promise.resolve(42);
const promise2 = new Promise(resolve => setTimeout(resolve, 1000, 'hello'));

customAll([promise1, promise2]).then(values => {
  console.log(values); // 输出: [42, 'hello']
});

7. Promise.allSettled - 手写实现和应用

Promise.allSettled()方法接受一个可迭代的对象作为参数,返回一个在所有给定的Promise已经resolvedrejected后解析的Promise,并带有一个对象数组,每个对象表示对应的Promise结果。

手写实现代码:

ini 复制代码
function customAllSettled(promises) {
  return new Promise(resolve => {
    const results = [];
    let completedPromises = 0;

    promises.forEach((promise, index) => {
      Promise.resolve(promise)
        .then(value => {
          results[index] = { status: 'fulfilled', value };
        })
        .catch(reason => {
          results[index] = { status: 'rejected', reason };
        })
        .finally(() => {
          completedPromises++;
          if (completedPromises === promises.length) {
            resolve(results);
          }
        });
    });
  });
}

示例代码:

ini 复制代码
const promise1 = Promise.resolve(42);
const promise2 = Promise.reject(new Error('Rejected'));

customAllSettled([promise1, promise2]).then(results => {
  console.log(results);
  /*
  输出: [
    { status: 'fulfilled', value: 42 },
    { status: 'rejected', reason: Error: Rejected }
  ]
  */
});

8. Promise.race - 手写实现和应用

Promise.race()方法同样接受一个可迭代的对象作为参数,返回一个新的Promise,一旦其中一个Promise解决或拒绝,返回的Promise将与之相同的解决值或拒绝原因解决或拒绝。

手写实现代码:

ini 复制代码
function customRace(promises) {
  return new Promise((resolve, reject) => {
    promises.forEach(promise => {
      Promise.resolve(promise)
        .then(value => {
          resolve(value);
        })
        .catch(error => {
          reject(error);
        });
    });
  });
}

示例代码:

javascript 复制代码
const promise1 = new Promise(resolve => setTimeout(resolve, 1000, 'first'));
const promise2 = new Promise(resolve => setTimeout(resolve, 500, 'second'));

customRace([promise1, promise2]).then(value => {
  console.log(value); // 输出: second
});

9. Promise.any - 手写实现和应用

Promise.any()方法接收一个可迭代的对象作为参数,返回一个新的Promise。一旦任何一个给定的Promise解决,它就会以该Promise的值解决。如果可迭代的对象中没有任何一个Promise解决,它就会失败并返回一个AggregateError,其中包含来自所有rejected Promises的原因。

手写实现代码:

ini 复制代码
function customAny(promises) {
  return new Promise((resolve, reject) => {
    let rejectedPromisesCount = 0;

    promises.forEach(promise => {
      Promise.resolve(promise)
        .then(value => {
          resolve(value);
        })
        .catch(error => {
          rejectedPromisesCount++;

          if (rejectedPromisesCount === promises.length) {
            reject(new AggregateError('All promises were rejected'));
          }
        });
    });
  });
}

示例代码:

javascript 复制代码
const promise1 = new Promise((resolve, reject) => setTimeout(reject, 1000, 'Rejected'));
const promise2 = new Promise(resolve => setTimeout(resolve, 500, 'Resolved'));
const promise3 = new Promise(resolve => setTimeout(resolve, 1500, 'Resolved Later'));

customAny([promise1, promise2, promise3])
  .then(value => {
    console.log(value); // 输出: Resolved
  })
  .catch(error => {
    console.error(error); // 不会执行
  });

总结

通过以上示例代码和解释,我们希望读者能更加深入地理解JavaScriptPromise方法的使用和作用。这些方法提供了强大的异步编程功能,使得处理异步操作变得更加简单和可靠。

后语

小伙伴们,如果觉得本文对你有些许帮助,点个👍或者➕个关注再走吧^_^ 。另外如果本文章有问题或有不理解的部分,欢迎大家在评论区评论指出,我们一起讨论共勉。

相关推荐
腾讯TNTWeb前端团队1 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰4 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪5 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪5 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy5 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom6 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom6 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom6 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom6 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom6 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试