ES6中的Promise对象

news2024/11/20 12:28:55

1. Promise是什么

Promise简单来说就是一个容器,里面保存着未来才会结束的事件的结果(这个事件就是异步操作)。Promise是一个对象(构造函数),可以获取异步操作的结果。

特点:

  • 对象的状态不受外界影响。有三种状态分别是Pending(进行中)、Fulfilled(已成功)、Rejected(已失败),这三种状态只能是异步的结果决定,其他操作都不能改变。

  • 状态改变后不会再变,任何时候都可以得到这个结果。状态改变只有两种情况分别是进行中变成成功、进行中变成失败。就是算已经发生变化,再对Promise添加回调函数
    也会立即得到这个结果,而事件(event)则是错过了监听就得不到结果了。

2. 为什么会出现Promise

因为之前解决异步操作使用回调函数,会嵌套多层,影响编写阅读,而Promise的出现更容易实现,使异步操作可以看出同步操作,阅读更容易。

3. Promise基本用法

const promise = new Promise((resolve, reject) => {
    if (/* 异步操作成功*/) {
        resolve(value)
    } else {
        reject(value)
    }
})

Promise构造函数接受一个函数作为参数,这个函数有两个参数分别是resolvereject,这两个参数也是函数。

resolve的作用就是将Promise对象的状态从进行中变为成功,在异步操作成功时进行调用,并将异步操作的结果作为参数传递出去。

reject的作用就是将Promise对象的状态从进行中变为失败,在异步操作失败时进行调用,并将异步操作的错误结果作为参数传递出去。

1. then回调函数

当Promise实例生成后可以使用then方法分别指定resolvedrejected状态的回调函数

then方法接受两个回调函数作为参数,第一个参数是Promise对象状态变为resolved时调用,第二个参数是Promise对象状态变为rejected时调用,其中第二个参数是可选的,
这两个函数的参数都是Promise对象传过的值当作为参数

promise.then((value) => {
    // 成功执行的代码
}, (error) => {
    // 失败执行的代码
})

2. then方法执行顺序

Promise对象建立后会立即执行,但是then方法指定的回调函数会在当前脚本所有同步任务执行完成后才会执行。通俗讲比如说现在处在一个方法中,then后还有代码,
比如正常的代码或者异步代码,它执行时会自动在正常代码(同步)后面执行。

const promise = () => {
    new Promise((resolve, reject) => {
        console.log('Promise实例')
        resolve('hello')
    }).then(result => {
        console.log('.then方法')
    })
    console.log('Promise外的打印');
    const list = [1, 2, 3];
    list.map((item, index) => {
        console.log(item, 'map打印' + index);
    })
}
promise();

在这里插入图片描述

3. resolve、reject函数的参数

reject函数的参数通常是Error对象的实例,表示抛出的错误。

resolve函数的参数除了正常值外,可以是Promise实例,如果是Promise实例则需要特别的注意。

如果传入的是一个实例p2,则本实例p1的状态取决于传入p2的状态,假如p1将要变成成功的状态,而传入的p2则为失败状态,则p1会执行失败状态时的代码。p1会等待p2实例的状态转变。

const p2 = new Promise((resolve, reject) => {
    reject(new Error('fail'));
})

const p1 = new Promise((resolve, reject) => {
    resolve(p2);
})

p1.then((result) => {
    console.log(result);
}).catch((error) => {
    console.log(error);
})
// 打印结果为:Error: fail

p2实例返回一个失败,本来p1是返回成功的,执行then方法,然后传入的参数是p2,而p2是一个实例,则此时的状态由p2决定,因此执行的是catch方法。

4. resolve 代码执行顺序

resolve函数所处脚本位置代码执行顺序和then方法一样,都是在本轮事件循环的末尾执行,总是晚于本脚本的同步任务。

const resolve = () => {
    new Promise((resolve, reject) => {
        resolve('状态成功后传递的值');
        console.log('脚本其他同步代码');
    }).then((result) => {
        console.log(result);
    })
}
resolve();

在这里插入图片描述

从上面的代码可以看出,resolve函数后面的代码先执行了。

其实按正常来说resolve返回了成功时传递的信息,Promise也就完成了自己的使命,后面就不应该再有代码出现了,因此当书写代码时应该写在最后,或者可以使用
return语句,这样不会产生意外。

new Promise((resolve, reject) => {
    return resolve(1);
    // 这样后面的语句不会执行
    console.log(2);
})

4. Promise.all()

Promise.all方法就是将多个Promise实例包装成一个新的Promise实例。

const p = Promise.all([p1, p2, p3]);

要求:

参数是一个数组形式,且每一项必须为Promise实例,假如不是实例则会调用Promise.resolve转化成Promise实例。

1. 新实例的状态

p的状态由参数的状态决定,分为两种情况。

第一种:所有的参数状态都变成Fulfilled(成功),则新实例变成Fulfilled,所有参数的返回值会组成一个数组,传递给新实例的回调函数。

第二种:如果有一个参数的状态变为Rejected(失败),则实例会变成Rejected,则会把这个结果传递给新实例的回调函数。

2. 参数实例是否有catch方法

如果作为参数的Promise实例自定义了catch方法,那么它被rejected时并不会触发Promise.all()的catch方法

这是为什么???

因为假如参数实例有catch方法时,执行完catch方法会返回一个新的Promise实例,此时的参数实例就会变为新返回的实例,
会变成resolved状态,会将catch方法执行完返回的值传递给all方法的回调函数。

// 参数p2有catch方法,最终结果为 ["hello", Error: 报错了]
const p1 = new Promise((resolve, reject) => {
        resolve('hello')
    }).then(result => result)
        .catch(e => e);

    const p2 = new Promise((resolve, reject) => {
        throw new Error('报错了');
    }).then(result => result)
        .catch(e => e);

    Promise.all([p1, p2])
        .then(result => console.log(result))  // ["hello", Error: 报错了]
        .catch(e => console.log(e));

// 参数p2没有catch方法,会执行all的catch方法,输出Error: 报错了
const p1 = new Promise((resolve, reject) => {
    resolve('hello')
}).then(result => result)
    .catch(e => e);

const p2 = new Promise((resolve, reject) => {
    throw new Error('报错了');
}).then(result => result)

Promise.all([p1, p2])
    .then(result => console.log(result))
    .catch(e => console.log(e)); // Error: 报错了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1000761.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

k8s优雅停服

在应用程序的整个生命周期中,正在运行的 pod 会由于多种原因而终止。在某些情况下,Kubernetes 会因用户输入(例如更新或删除 Deployment 时)而终止 pod。在其他情况下,Kubernetes 需要释放给定节点上的资源时会终止 po…

轻松省下大笔费用!5个你不得不知道的云渲染省钱攻略

 在今天的数字化时代,云渲染正以其强大的计算能力和高效的渲染速度成为许多设计师和创意工作者的首选。然而,使用云渲染服务也可能意味着额外的费用开销。幸运的是,本文将为您揭示5个轻松省下大笔费用的云渲染省钱攻略&#xff…

巨人互动|Facebook海外户Facebook客户反馈分数

Facebook客户反馈分数是一项用于衡量用户对Facebook产品和服务满意度的指标。该指标被广泛应用于各种调研和评估活动,帮助Facebook了解用户对其平台和功能的意见和建议,并从中识别出改进的机会。 巨人互动|Facebook海外户&Facebook新闻提要的算法&am…

门阀-bitlocker

一、bitlocker,可给C盘,D盘其他盘,&U盘加密; 1.1此处只涉及D盘加密 网址:如何开启BitLocker加密 保存恢复码 数据解密 基础篇【夻白咏技 057期】 - YouTube 步骤须知: D盘操作步骤: 1&am…

2023年锂行业研究报告

第一章 行业概况 1.1 定义 锂行业,作为有色金属行业中稀有金属子行业的重要组成部分,近年来受到了广泛的关注和研究。锂矿经过冶炼加工,可以得到多种锂盐产品。这些锂盐产品在传统工业中有着广泛的应用,尤其是在玻璃和陶瓷制造、…

勒索病毒最新变种.halo勒索病毒来袭,如何恢复受感染的数据?

摘要: .halo勒索病毒已成为数字世界中的威胁,通过高级加密技术将文件锁定,并要求支付赎金。本文91数据恢复将深入介绍.halo勒索病毒的工作原理,提供解锁被感染文件的方法,以及探讨如何有效预防这一威胁。如果您正在经…

串行通信协议

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、UART二、SPI二、IIC 前言 UART为异步串行通信,使用各自的时钟控制数据的发送和接受过程,不使用同步时钟,而是使用一些特…

苏宁API接口解析,实现按关键字搜索suning商品

苏宁API接口提供了多种搜索商品的方式,其中包括按关键字搜索。下面是一个简单的示例,演示如何使用苏宁API接口实现按关键字搜索商品: 点击获取key和secret 苏宁易购按关键字搜索suning商品 API 返回值说明 请求参数 请求参数:q…

UG\NX二次开发 计算一个向量的反向向量UF_VEC3_negate

文章作者:里海 来源网站:王牌飞行员_里海_里海NX二次开发3000例,里海BlockUI专栏,C\C++-CSDN博客 简介: UG\NX二次开发 计算一个向量的反向向量UF_VEC3_negate 效果: 代码: #include "me.hpp"void ufusr(char* param, int* retcode, int paramLen) {UF…

腾讯云4核8G服务器CVM S5性能测评及优惠价格表

腾讯云4核8G服务器CVM标准型S5实例性能测评,包括CPU型号、内存、系统盘、CVM实例规格性能测评,腾讯云4核8G租用优惠价格表,腾讯云服务器网分享腾讯云4核8G服务器CVM S5性能测评和租用费用: 目录 腾讯云4核8G服务器CVM S5性能测评…

单片机之硬件记录

一、概念 VBAT 当使用电池或其他电源连接到VBAT脚上时,当VDD断电时,可以保存备份寄存器的内容和维持RTC的功能。如果应用中没有使用外部电池,VBAT引脚应接到VDD引脚上。 VCC:Ccircuit 表示电路的意思,即接入电路的电压&#x…

【数据结构】【C++】平衡搜索二叉树的模拟实现(AVL树)

【数据结构】&&【C】平衡搜索二叉树的模拟实现(AVL树) 一.AVL树的性质二.AVL树的模拟实现①.AVL树结点的定义②. AVL树的插入③.平衡因子的更新④.左单旋⑤.右单旋⑥.双旋(左右旋/右左旋)⑧.AVL树的删除⑨.检查是否是AVL树 三.完整代码 一.AVL树的性质 AVL…

中国电子科技集团公司第十四研究所(中电14)部门科室介绍、能力要求、待遇薪资

0.基本 雷达中电第一所南京 1.一部(总体部) 与军队对接需求雷达的选型和交付能力要求:担责任、知识面广(天线、射频、信号处理、数据处理)、学习能力、对外沟通能力科室: 101:空军&#xff0…

项目无故启动不了

隔了一个周末回来上班,启动项目,发现项目启动不了,根本没有动过代码。 报错: 解决方案: 代码没有改过,无缘无故启动不了项目,肯定是环境的问题。 找到这个类所在的依赖, 删掉重新…

Java的XWPFTemplate工具类导出word.docx的使用

依赖 <!-- word导出 --><dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.7.3</version></dependency><!-- 上面需要的依赖--><dependency><groupId>org.ap…

华为云云耀云服务器L实例评测| CloudExplorer Lite轻量级云平台管理华为云云耀云服务器L实例

华为云云耀云服务器L实例评测&#xff5c; CloudExplorer Lite轻量级云平台管理华为云云耀云服务器L实例 一、云耀云服务器L实例介绍1.1 云耀云服务器L实例简介1.2 云耀云服务器L实例特点1.3 云耀云服务器L实例使用场景 二、 CloudExplorer Lite介绍2.1 CloudExplorer Lite简介…

练习接口测试详细步骤

最近一段时间学了Python语言&#xff0c;重新学了 Java&#xff0c;js&#xff0c;html语言&#xff0c;CSS&#xff0c;linux&#xff0c;一堆测试工具&#xff1b;唉&#xff5e; 在接触接口测试过程中补了很多课&#xff0c; 终于有点领悟接口测试的根本&#xff1b; 偶是…

为何不建议使用Java自带的线程池

Executors Executors是java自带的线程池。Executors 里面默认提供的几个线程池是有一些弊端的&#xff0c;如果是不懂多线程、或者是新手直接盲目使用&#xff0c;就可能会造成比较严重的生产事故。 Executors.newFixedThreadPool(10); Executors.newSingleThreadExecutor();…

Python语义分割与街景识别(3):数据集准备

前言 本文主要用于记录我在使用python做图像识别语义分割训练集的过程&#xff0c;由于在这一过程中踩坑排除BUG过多&#xff0c;因此也希望想做这部分内容的同学们可以少走些弯路。 本文是python语义分割与街景识别第三篇&#xff0c;关于数据集准备的内容。 一、自己制作数…

【transformer】动手学ViT

AN IMAGE IS WORTH 16X16 WORDS: TRANSFORMERS FOR IMAGE RECOGNITION AT SCALE 摘要Method实验代码-基于pytorchTraining Visual Transformer on Dogs vs Cats Data注释一些词汇 ICLR2021 一幅图像值16x16个字&#xff1a;用于图像识别的transformers 将纯Transformer结构运用…