一文了解异步编程

news2024/11/28 7:28:43

promise

什么是promise

promise是异步编程的一种解决方案,从语法上来说,Promise是一个对象,从它可以获取异步操作的消息

ES6规定,Promise对象是一个构造函数,接受一个函数作为参数,这个函数会立即执行,该函数的两个参数分别是resolve和reject,它们是两个函数。
resolve函数的作用是将Promise对象的状态从Pending变成Resolved,在异步操作成功时调用并将异步操作结果作为参数传递出去;reject函数的作用是,将Promise对象的状态从Pending变成Rejected,在异步操作失败时调用,并将异步操作报出的错误作为参数传递出去。
promise实例生成后,可以用then方法指定成功后或失败后的回调函数

promise状态

  1. 待定(Pending):初始状态,当执行executor中的代码时处于该状态
  2. 已兑现(resolved/fulfilled):操作成功,执行了resolve时,处于该状态
  3. 已拒绝(rejected):意味着操作失败,执行了reject时,处于该状态

promise的特点

1.不受外界的影响。只有异步操作结果可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
2. 一旦状态改变就不会再变,任何时候都可以得到这个结果

promise的缺点

  1. 无法取消Promise,一旦新建它就会立即执行,无法中途取消。
  2. 不设置回调函数,promise内部抛出的错误不会反映到外部。
  3. 当处于Pending状态时,无法得知目前进展到哪一个阶段(刚刚开始,还是即将完成)

promise的方法

  • then
  1. Promise实例具有then方法,then方法是定义在原型对象上的。
  2. then方法接受两个参数:第一个参数是fulfilled状态的回调函数,第二个参数是Rejected的回调函数
  3. then方法可以被多次调用,每次调用都会传入对应的fulfilled回调
  4. then方法返回的是一个新的Promise实例。因此可以采用链式写法。
    then中return 的值决定新返回的promise的状态:
    非promise:成功
    promise:状态与该promise一致
    抛出异常:失败
  • catch
    用于发生错误时的回调函数
    事实上catch方法也是会返回一个Promise对象的,所以catch方法后面我们可以继续调用then方法或catch方法。
    promise对象的错误具有冒泡性质,会一直向后传递,直到被捕获为止

  • finally

    finally方法用于不管Promise对象最后状态如何都会执行的操作。
    他接受一个普通函数作为参数,该函数不管怎样都必须执行。

  • resolve

    有时需要将现有对象转为Promise对象,Promise.resolve方法就起到了这个作用。

    1. 参数是一个Promise实例,那么Promise.resolve将不做任何修改,原封不动的返回实例
    2. 参数是一个thenable对象,Promise.resolve方法会将这个对象转为Promise对象,然后立即执行thenable对象的then方法.
    3. 参数不具有then方法的对象或根本不是对象或没有参数,那么Promise.resolve方法返回一个新的Promise对象,状态为Resolved
  • reject

    Promise.reject方法会返回一个新的promise实例,状态为Rejected,无论参数是何形态

  • all

    promise.all方法将多个Promise实例包装成一个新的Promise实例。如果不是Promise实例就会先调用Promise.resolve方法,将参数转换为Promise实例
    promise.all方法的参数不一定是数组,但是必须具有Iterator接口

    1. 当所有的Promise状态变成fulfilled状态时,新的promise状态才会变成fulfilled,并将所有Promise的返回值组成一个数组
    2. 当有一个Promise状态为rejected时,新的Promise状态为rejected,并且返回第一个rejected返回值作为参数
  • race

    promise.race方法将多个Promise实例包装成一个新的Promise实例。
    只要有一个实例先改变状态,新的promise状态就跟着改变,并返回率先改变的Promise实例的返回值作为参数

Iterator/for…of

什么是Iterator

它是一种接口,目的是为所有数据结构提供统一的访问机制,即for…of循环

Iterator遍历过程

  1. 创建一个指针对象,指向当前数据的起始位置
  2. 第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。
  3. 不断调用指针对象的next方法,直到它指向数据结构的结束位置。

每次调用next方法都会返回数据结构的当前成员的信息。
具体返回一个包含value和done两个属性的对象。其中value属性是当前成员的值,done属性是一个布尔值,表示遍历是否结束。

原生具备Iterator接口的数据

String、Array、Map、Set、函数的arguments对象、NodeList对象

Iterator应用

JavaScript中语法:for …of、展开语法、yield*、解构赋值;

创建一些对象时:new Map([Iterable])、new WeakMap([iterable])、new Set([iterable])、new WeakSet([iterable]);

一些方法的调用:Promise.all(iterable)、Promise.race(iterable)、Array.from(iterable);

迭代器中断

迭代器在某些情况下会在没有完全迭代的情况下中断,比如遍历的过程中通过break、continue、return、throw中断了循环操作;

Iterator接口与Generator

在这里插入图片描述

Generator

什么是生成器

Generator函数是ES6提供的一种异步解决方案,执行Generator函数会返回一个遍历器对象,返回的遍历器对象。
形式上Generator函数是一个普通函数但是有两个特征:

  1. function关键字与函数名之间有一个星号(*)
  2. 函数体内部使用yield语句定义不同的内部状态(yield的意思是产出)

yield表达式

yield语句是暂停标志
yield只能在Generator函数里面,用在其他地方会报错
yield表达式如果用在另一个表达式中,必须放在圆括号里面

如果yield表达式后面跟的是一个遍历器对象,需要在yield表达式后面加上星号,表明它返回的是一个遍历器对象。这被称为yield*表达式。

遍历器对象的next方法的运行逻辑如下。

  1. 遇到yield语句就暂停执行后面的操作,并将紧跟在yield后的表达式的值作为返回对象的value值。
  2. 下一次调用next方法时再继续往下执行,直到遇到下一条yield语句。
    3.如果没有再遇到新的yield语句,就一直到函数结束,直到return语句为止,并将return语句后面的表达式值作为返回对象的value属性值
  3. 如果该函数没有return语句,则返回对象的value属性值为undefined

yield和return的异同

  1. 都能返回紧跟在语句后面的那个表达式的值
  2. 每次遇到yield,函数暂停执行,下一次再从该位置继续向后执行,return语句不具备位置记忆功能
  3. 一个函数里面只能执行一次return语句,但可以执行多次yield表达式

next方法参数

yield表达式本身没有返回值,或者说总是返回undefined,next方法可以带一个参数,该参数会被当作 【上一个yield表达式】的返回值,所以第一次使用next方法时传递参数是无效的。

Generator.prototype.throw()

Generator函数返回的遍历器对象,都有一个throw方法,可以在函数体外抛出错误,然后在Generator函数体内捕获。

Generator.prototype.return()

Generator函数的遍历器对象中还有一个return方法,可以返回给定的值,并且终结遍历Generator函数。

for…of循环

for…of循环可以自动遍历Generator函数运行时生成的Iterator对象,不需要调用next方法(不包括return语句)

for…of与for…in的区别

  1. for-in适合遍历对象属性,for-of适合遍历数组
  2. for…in 循环:只能获取对象的键名,不能获得键值;for…of循环:允许便利获得键值。
  3. for…in循环可以可枚举的属性,for…of遍历的是可迭代的
  4. for-of不能直接遍历普通的对象,需要通过Object.keys()搭配使用

async/await

async是什么

用一句话来说,他就是Generator函数的语法。
async函数就是将Generator函数的星号换成async,将yield换成了await

async对Generator函数的改进

  1. 内置执行器
    Generator函数的执行必须依靠执行器,所以才有了co模块,而async自带执行器
  2. 更好的语义
    async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。
  3. 更广的适用性
    co模块约定,yield命令后面只能是Thunk函数或Promise对象,而async函数的await命令后面,可以是Promise对象和原始类型的值(数值、字符串和布尔值,但这时等同于同步操作)
  4. 返回值是Promise
    async函数的返回值是Promise,比Generator函数的返回值是Iterator对象方便了许多。可以用then方法指定下一步的操作
    进一步说async函数完全可以看作由多个异步操作包装成的一个Promise对象,而await命令就是内部then命令的语法糖

async语法

  1. async函数返回一个Promise对象,async函数内部return语句返回的值,会成为then方法回调函数的参数。
  2. async函数返回的Promise对象必须等到内部所有await命令后面的Promise对象执行完成后才会发生状态改变,除非遇到return语句或者抛出错误。

await命令

  1. 正常情况下,await命令后面是一个Promise对象。如果不是,会被转成一个立即resolve的Promise。
  2. 只要一个await语句后面的Promise变成reject,那么整个async函数都会中断执行
  3. 如果await后面的异步操作出错,那么等同于async函数返回的Promise对象被reject

回调地狱

为了能够拿到异步的数据,使用了大量的回调函数,来获取将来异步执行成功之后的数据。使得代码更加难以理解和维护。

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

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

相关文章

Long类型返回前端精度丢失

【1】给前端返回Long会出现精度丢失问题 在《阿里巴巴Java开发手册》中,有一条关于前后端超大整数返回的规约,具体内容如下: 【2】问题复现 后端直接用postman测试接口,返回数据没有问题。但是前端访问接口的时候,发…

系统化了解Micrometer

本文从官方文档整理出一篇系统化全面了解的文章, 后续可能会慢慢补上源码层面的解析: https://micrometer.io/docs 学习本文的目的在于深入了解中间件的监控模块的设计, 先看看主流的做法于核心思想 本文的引用来的笔者的理解于备注 需要做的是: 先理解功能存在的理由设计模式…

kibana 代码执行 (CVE-2019-7609)

漏洞原理 “原型污染”是一种针对JS语言开发的攻击方法。JS语言中,每一个对象都是有其原型(proto)的,而该原型又有其自己的原型对象,直到某个对象的原型为null。而如果JS对其中定义的对象原型的属性读写缺乏控制&…

进程程序替换+简易版shell实现

索引 进程程序替换如何进行程序替换不同程序替换函数之间的区别系统接口调用其他语言的函数替换函数execle 简易版shell实现 进程程序替换 什么是进程程序替换? 指在一个正在运行的进程中,将原来的程序替换成新的程序的过程。 eg:如果我们想…

I IntelliJ IDEA 2023.1 最新解锁方式,支持java20,让Coding飞一会儿

IntelliJ IDEA 2023.1 最新变化 在 IntelliJ IDEA 2023.1 中,我们根据用户的宝贵反馈对新 UI 做出了大量改进。 我们还实现了性能增强,从而更快导入 Maven,以及在打开项目时更早提供 IDE 功能。 新版本通过后台提交检查提供了简化的提交流程…

Android不基于第三发依赖包解析shp文件(2)

接着上篇文章继续 2)Point (点)   一个 Point 由一对双精度坐标组成,存储顺序为 X,Y。    /*** PointGeometry记录读取* */static Geometry renderPointGeometry(byte[] recordContent,GeometryFactory geometryFactory) {int shapetype2

N轴机械臂的MDH正向建模,及python算法

目录 一、前言二、三维空间的坐标系变换三、MDH建模要点四、MDH的变换矩阵推导五、机械臂MDH的python模型六、python源码 一、前言 如果机器人工程师缺乏机器人学理论的支撑和足够的认识,那么随着机器人项目的深入推进,可能会越走越艰难,所谓…

【Lambda】集合的Lambda表达式

【Lambda】集合的Lambda表达式 【一】Stream的方法介绍【1】Stream里常用的方法【2】collect(toList()) & filter【3】map【4】flatMap【5】max&min【6】reduce 【二】常用案例总结【1】准备方法查询数据库获取List结果【2】取值【3】分组【4】去重【5】排序【6】list的…

uniapp制作水印相机给图片添加水印并且保存图片至本地

uniapp保存文件的三种方式 文件主要分为两大类: 1.代码包文件:代码包文件指的是在项目目录中添加的文件。 2.本地文件:通过调用接口本地产生,或通过网络下载下来,存储到本地的文件。 其中本地文件又分为三种&#…

【K8s】Service详解

文章目录 一、Service介绍1、认识Service2、kube-proxy的三种工作模式3、Service的类型 二、Service的使用1、实验数据准备2、Service类型为ClusterIP补充:Endpoints补充:负载分发策略 3、Service类型为HeadLiness3、Service类型为NodePort4、Service的类…

Ovito渲染技巧之体系边界识别

关注 M r . m a t e r i a l , \color{Violet} \rm Mr.material\ , Mr.material , 更 \color{red}{更} 更 多 \color{blue}{多} 多 精 \color{orange}{精} 精 彩 \color{green}{彩} 彩! 主要专栏内容包括: †《LAMMPS小技巧》: ‾ \textbf…

性能、性能还是性能---下一代Android性能框架分析

性能优化的重要性和难度毋庸置疑,事实上,性能优化也是一个永无止境的游戏,总会发现有一些东西需要优化。但是不可避免的是,这也是一个边际效益递减的事情,项目或应用获得的收益在一定程度上也会逐渐降低。What’s new …

ReentrantLock 原理

目录 ReentrantLock 概述 ReentrantLock 的原理 什么是 AQS ? 获取锁资源(以⾮公平锁为例) tryAcquire addWaiter acquireQueued 释放锁资源 ⾮公平锁体现在哪⾥? 调试代码 总结 ReentrantLock 概述 ReentrantLock是Lock接⼝的默认实现,是⼀…

【Linux】-关于Linux的指令(下)

💖作者:小树苗渴望变成参天大树 ❤️‍🩹作者宣言:认真写好每一篇博客 💨作者gitee:gitee 💞作者专栏:C语言,数据结构初阶,Linux,C 文章目录 前言一、时间相关的指令二、cal指令三、find -name指…

Centos7 经典模式安装GBase 8s 图文教程

Centos7安装GBase 8s 图文教程 前言1.1 硬件要求1.2 系统要求1.3 虚拟 PC 软件1.4 安装及配置数据库服务器1.4.1 创建 gbasedbt 组和用户1.4.2 创建 GBase 8s 数据库安装目录1.4.3 上传并解压安装包1.4.4 执行安装 参考文献 前言 本篇博文分享如何在Centos7 x86架构的系统中安…

第2章-Selenium-API操作

目标: 1. 熟练应用八种元素定位方式 2. 掌握对元素和浏览器的操作方法 3. 掌握键盘鼠标的操作 4. 掌握元素等待的操作 5. 掌握下拉选择框、 警告框和滚动条的操作 6. 掌握如何切换frame框架和多窗口 7. 掌握如何实现窗口截图 1.元素定位 1. 掌握id、 name、 cla…

【leetcode】622 二叉树的最大宽度

题目描述 给你一棵二叉树的根节点 root ,返回树的 最大宽度 。 树的 最大宽度 是所有层中最大的 宽度 。 每一层的 宽度 被定义为该层最左和最右的非空节点(即,两个端点)之间的长度。将这个二叉树视作与满二叉树结构相同&#…

MATLAB 之 M 文件和程序控制结构(顺序、选择、循环)

文章目录 一、M 文件1. M 文件的建立与打开1.1 建立新的 M 文件1.2 打开已有的 M 文件 2. M 文件的分类 二、 程序控制之顺序结构1. 数据的输入2. 数据的输出3. 程序的暂停 三、程序控制之选择结构1. if 语句2. switch 语句3. try 语句 四、程序控制之循环结构1. for 语句2. wh…

畸变像差校正技术(畸变相位补偿)发展现状及其仿真实验研究-技术汇总-Matlab代码

▒▒本文目录▒▒ 一、引言二、物理方法2.1 基于二次曝光法的畸变像差补偿仿真实验验证 三、数值方法3.1 基于主成分分析法的畸变像差补偿仿真实验验证3.2 基于标准多项式拟合法的畸变像差校正仿真实验验证3.3 基于最小二乘拟合法的畸变像差校正仿真实验验证3.4 基于泽尼克多项…

Simulink 自动代码生成电机控制——永磁同步电机参数获取

目录 前言 极对数测量 电阻测量(Rs) 电感测量(Ld和Lq) 磁链测量 总结 前言 在建模之前或者需要更换一个新电机,需要获取目标电机的电气参数,如果参数不对,对于电流环参数的整定&#xff0…