深入理解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方法的使用和作用。这些方法提供了强大的异步编程功能,使得处理异步操作变得更加简单和可靠。

后语

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

相关推荐
hedley(●'◡'●)20 分钟前
基于cesium和vue的大疆司空模仿程序
前端·javascript·vue.js·python·typescript·无人机
qq5_81151751522 分钟前
web城乡居民基本医疗信息管理系统信息管理系统源码-SpringBoot后端+Vue前端+MySQL【可直接运行】
前端·vue.js·spring boot
百思可瑞教育23 分钟前
构建自己的Vue UI组件库:从设计到发布
前端·javascript·vue.js·ui·百思可瑞教育·北京百思教育
百锦再23 分钟前
Vue高阶知识:利用 defineModel 特性开发搜索组件组合
前端·vue.js·学习·flutter·typescript·前端框架
CappuccinoRose1 小时前
JavaScript 学习文档(二)
前端·javascript·学习·数据类型·运算符·箭头函数·变量声明
这儿有一堆花1 小时前
Vue 是什么:一套为「真实业务」而生的前端框架
前端·vue.js·前端框架
全栈前端老曹1 小时前
【MongoDB】深入研究副本集与高可用性——Replica Set 架构、故障转移、读写分离
前端·javascript·数据库·mongodb·架构·nosql·副本集
NCDS程序员2 小时前
v-model: /v-model/ :(v-bind)三者核心区别
前端·javascript·vue.js
夏幻灵2 小时前
CSS三大特性:层叠、继承与优先级解析
前端·css
小杨同学呀呀呀呀2 小时前
Ant Design Vue <a-timeline>时间轴组件失效解决方案
前端·javascript·vue.js·typescript·anti-design-vue