PromisesMDN 非官方文档详解

一、Promise概述

Promise是一种用于处理异步操作的技术,它是一种异步计算的抽象,简单来说就是实现异步编程的重要手段。Promise可以让我们在代码内部预先定义好异步操作成功后的结果值、失败后的处理逻辑和如何响应异步操作结果的状态。

以下是Promise的基本用法:

const promise = new Promise(function(resolve, reject) {
   // 在这里执行异步操作
   // 成功时调用resolve,失败时调用reject
});

promise.then(function(successResult) {
   // 对于成功的处理逻辑
}).catch(function(errorResult) {
   // 对于失败的处理逻辑
});

首先我们创建了一个Promise实例,其中包含了resolve和reject两个参数,在异步操作成功时调用resolve,并传递异步计算的结果给到then方法继续处理。在异步操作抛出错误时,我们调用reject,并将错误信息传给catch方法进行错误处理。

二、Promise状态

Promise有3种状态:

  • pending – 未完成状态,这时候既不是成功也不是失败。
  • fulfilled – 成功状态,表示异步操作已经完成。
  • rejected – 失败状态,表示异步操作已经失败。

在Promise实例创建时,状态为pending。当调用resolve时,状态变为fulfilled;调用reject时,状态变为rejected。Promise状态一旦确定就不能再次改变。

以下是实现Promise状态的例子:

let myPromise = new Promise((resolve, reject) => {
    let isSuccess = true; // 异步操作是否成功
    if (isSuccess) {
        resolve("异步操作成功了!");
    } else {
        reject("异步操作失败了!");
    }
});

myPromise.then((result) => {
    console.log(result);
}, (error) => {
    console.log(error);
});

上述代码中,当异步操作成功时,我们调用了resolve并传递了一个成功的结果给到then。在异步操作失败时,我们调用了reject并传递了错误信息到catch方法。

三、 Promise API

1. Promise.all()

Promise.all接收一个Promise对象数组作为参数,当所有Promise对象完成时,它会返回一个由每个Promise结果值组成的数组。如果有任何一个Promise对象失败,它 immediately 也会失败,随后的 then 方法不会执行,而是进入 catch。

以下是Promise.all的例子:

let promisesList = [Promise.resolve(3), Promise.resolve(4), new Promise((resolve, reject) => {
    setTimeout(function () {
        resolve('done');
    }, 1000);
})];

Promise.all(promisesList).then(function (results) {
    console.log(results);
}).catch(function (error) {
    console.error(error);
});

当promisesList中所有的Promise对象完成时,则会打印值为3,4,和’done’的数组results。

2. Promise.race()

Promise.race接受一组Promise对象作为参数,并返回第一个完成后的Promise对象的结果,不管它是成功还是失败。如果传入一个空数组,Promise.race 将永远处于等待状态。

以下是Promise.race的例子:

let p1 = new Promise(function(resolve, reject) {
    setTimeout(resolve, 500, "p1");
});

let p2 = new Promise(function(resolve, reject) {
    setTimeout(resolve, 200, "p2");
});

Promise.race([p1, p2]).then(function(value) {
  console.log(value);
  // 在p2成功之后就立即完成
});

当p2成功时立即完成该Promise,返回值为’p2’。

3. Promise.reject()

Promise.reject是一个标准的Promise reject状态函数,它返回一个带有拒绝原因参数的Promise对象。

Promise.reject("Something went wrong").catch((reason) => {
    console.log('Handle rejected promise ('+reason+') here.');
});

在使用Promise.reject时,我们将一个错误的消息传递给了catch方法,以便我们能够及时处理Promise对象的拒绝状态。

4. Promise.resolve()

Promise.resolve是一个标准的Promise resolved状态函数,它返回一个解决的Promise对象。

Promise.resolve(4).then((result) => {
    console.log(result + 5); // 输出 9
});

在上述代码中,我们将数字4传递给了Promise.resolve,当Promise对象解决时,输出值为9。

四、Promise并行与串行

1. Promise并行

假设我们有多个异步任务需要同时进行,完成这些异步任务的最终结果是我们需要的。这时候可以使用Promise.all方法,根据Promise的规范,只有在所有Promise都同意完成后,Promise.all才会返回复合Promise中所有成功完成操作的结果的一个Promise。

以下是Promise并行的例子:

// 模拟异步任务
function task(num) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      resolve(num);
    }, Math.random() * 3000);
  });
}

// 多个异步任务同时进行
Promise.all([task(1), task(2), task(3)]).then(function(results) {
  console.log(results); // [1,2,3]
}).catch(function(err) {
  console.error(err);
});

在上述代码中,我们使用Promise.all方法来实现多个异步任务的同时进行,当这些异步任务全部完成后,我们才会执行then方法,输出每个任务的结果值。

2. Promise串行

当需要让多个异步任务依次顺序执行时,可以使用Promise.then方法。这种方式也称为链式调用。

以下是Promise串行的例子:

// 模拟异步任务
function task(num) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      resolve(num);
    }, Math.random() * 3000);
  });
}

task(1)
.then(function(result) {
  console.log(result);
  return task(2);
})
.then(function(result) {
  console.log(result);
  return task(3);
})
.then(function(result) {
  console.log(result);
})
.catch(function(err) {
  console.error(err);
});

在上述代码中,我们使用Promise.then方法来实现异步任务的顺序执行,每一个任务都必须在上一个任务完成后才能执行。使用then方法将任务分别串联起来,并输出每一个结果值。

五、Promise优缺点

1. Promise优点

  • 解决了回调地狱问题
  • 更易于代码维护和阅读
  • 提供了处理异步操作更好的方式

2. Promise缺点

  • 无法取消Promise
  • 在适用的情况下,速度比传统回调慢,具有更多的内存消耗
  • Promise 在处理硬盘异步IO(文件系统)时存在问题

六、结论

Promise是Javascript中异步编程的重要手段,通过引入Promise规范,我们可以更好地处理异步操作,避免回调地狱等问题;同时也提供了多种优化性能和提高可读性的API。

不过Promise也有一些缺点,在使用过程中需要仔细斟酌,根据实际情况选择是否使用。

原创文章,作者:JMYMW,如若转载,请注明出处:https://www.506064.com/n/332944.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
JMYMW的头像JMYMW
上一篇 2025-01-27 13:34
下一篇 2025-01-27 13:34

相关推荐

  • 使用Spire.PDF进行PDF文档处理

    Spire.PDF是一款C#的PDF库,它可以帮助开发者快速、简便地处理PDF文档。本篇文章将会介绍Spire.PDF库的一些基本用法和常见功能。 一、PDF文档创建 创建PDF文…

    编程 2025-04-29
  • Python爬虫文档报告

    本文将从多个方面介绍Python爬虫文档的相关内容,包括:爬虫基础知识、爬虫框架及常用库、爬虫实战等。 一、爬虫基础知识 1、爬虫的定义: 爬虫是一种自动化程序,通过模拟人的行为在…

    编程 2025-04-28
  • Python生成PDF文档

    Python是一门广泛使用的高级编程语言,它可以应用于各种领域,包括Web开发、数据分析、人工智能等。在这些领域的应用中,有很多需要生成PDF文档的需求。Python有很多第三方库…

    编程 2025-04-28
  • Linux sync详解

    一、sync概述 sync是Linux中一个非常重要的命令,它可以将文件系统缓存中的内容,强制写入磁盘中。在执行sync之前,所有的文件系统更新将不会立即写入磁盘,而是先缓存在内存…

    编程 2025-04-25
  • 神经网络代码详解

    神经网络作为一种人工智能技术,被广泛应用于语音识别、图像识别、自然语言处理等领域。而神经网络的模型编写,离不开代码。本文将从多个方面详细阐述神经网络模型编写的代码技术。 一、神经网…

    编程 2025-04-25
  • Linux修改文件名命令详解

    在Linux系统中,修改文件名是一个很常见的操作。Linux提供了多种方式来修改文件名,这篇文章将介绍Linux修改文件名的详细操作。 一、mv命令 mv命令是Linux下的常用命…

    编程 2025-04-25
  • git config user.name的详解

    一、为什么要使用git config user.name? git是一个非常流行的分布式版本控制系统,很多程序员都会用到它。在使用git commit提交代码时,需要记录commi…

    编程 2025-04-25
  • 详解eclipse设置

    一、安装与基础设置 1、下载eclipse并进行安装。 2、打开eclipse,选择对应的工作空间路径。 File -> Switch Workspace -> [选择…

    编程 2025-04-25
  • C语言贪吃蛇详解

    一、数据结构和算法 C语言贪吃蛇主要运用了以下数据结构和算法: 1. 链表 typedef struct body { int x; int y; struct body *nex…

    编程 2025-04-25
  • Python输入输出详解

    一、文件读写 Python中文件的读写操作是必不可少的基本技能之一。读写文件分别使用open()函数中的’r’和’w’参数,读取文件…

    编程 2025-04-25

发表回复

登录后才能评论