#Js篇:async函数await 命令

news/2024/2/28 1:36:26

async函数

定义

是 Generator 函数的语法糖。

Generator 函数的引入为 JavaScript 中异步编程提供了一种更为直观和易于理解的方式

返回

async函数的返回值是Promise对象,

基本用法

使用 async 关键字声明的函数会自动返回一个 Promise 对象,无需手动创建。这使得异步函数更容易与其他异步操作协同工作。

async函数返回一个 Promise 对象,可以使用then方法添加回调函数。

当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。

async function f() {return 'hello world';
}f().then(v => console.log(v))
// "hello world"

async函数内部return语句返回的值,会成为then方法回调函数的参数。

上面代码中,函数f内部return命令返回的值,会被then方法回调函数接收到

async函数内部抛出错误,会导致返回的 Promise 对象变为reject状态。抛出的错误对象会被catch方法回调函数接收到。

await命令

定义

正常情况下,await命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值。

错误处理

如果await后面的异步操作出错,那么等同于async函数返回的Promise对象被reject。

防止出错的方法,也是将其放在try...catch代码块之中

如果有多个await命令,可以统一放在try...catch结构中。

async function main() {try {const val1 = await firstStep();const val2 = await secondStep(val1);const val3 = await thirdStep(val1, val2);console.log('Final: ', val3);}catch (err) {console.error(err);}
}
使用注意点

第一点,前面已经说过,await命令后面的Promise对象,运行结果可能是rejected,所以最好把await命令放在try...catch代码块中。

第二点,多个await命令后面的异步操作,如果不存在继发关系,最好让它们同时触发。

上面代码中,getFoogetBar是两个独立的异步操作(即互不依赖),被写成继发关系。这样比较耗时,因为只有getFoo完成以后,才会执行getBar,完全可以让它们同时触发。

// 写法一
let [foo, bar] = await Promise.all([getFoo(), getBar()]);// 写法二
let fooPromise = getFoo();
let barPromise = getBar();
let foo = await fooPromise;
let bar = await barPromise;

上面两种写法,getFoogetBar都是同时触发,这样就会缩短程序的执行时间。

第三点,await命令只能用在async函数之中,如果用在普通函数,就会报错。

async 函数与 Promise的区别

  1. 返回值类型:
    • async 函数总是返回一个 Promise 对象。即使在函数内部使用 return 返回非 Promise 类型的值,它也会被隐式地包装成一个解决的 Promise 对象。
    • 普通函数返回的是函数执行的结果,而 async 函数返回的是一个 Promise 对象。
  2. 语法简洁性:
    • async 函数的语法更为简洁,可以使用 await 关键字来等待异步操作的完成,而不需要手动创建 Promise 链。
    • Promise 需要通过 .then().catch() 来处理异步操作的结果,导致可能出现较深的嵌套(回调地狱)。
  3. 错误处理:
    • async 函数内部可以使用 try...catch 来捕获和处理异步操作的错误,使得错误处理更加方便。
    • Promise 中,错误处理通常通过 .catch() 方法,或者在 .then() 中的第二个参数进行。
  4. 使用场景:
    • async 函数适用于更直观地编写异步代码,特别是在处理多个异步操作时。
    • Promise 通常用于处理单一的异步操作,或者在不使用 async/await 语法的情况下进行异步编程。
  5. await 的使用:
    • await 只能在 async 函数内部使用,用于等待一个 Promise 对象解决,并返回其解决值。
    • 在普通函数或全局作用域中,无法使用 await 关键字。
  6. 可读性:
    • 使用 async/await 语法可以使异步代码更加直观和可读,避免了回调地狱,提高了代码的可维护性。
    • Promise 链的可读性较差,尤其是在处理多个异步操作时。

综合来说,async/await 是一种更现代、更清晰的异步编程方式,而 Promise 仍然是底层的异步处理机制,可以在某些场景下继续发挥作用。通常,使用 async/await 更容易理解和维护异步代码。


http://www.ppmy.cn/news/1242074.html

相关文章

flask依据现有的库表快速生成flask实体类

flask依据现有的库表快速生成flask实体类 在实际开发过程中,flask的sqlalchemy对应的model类写起来重复性较强,如果表比较多会比较繁琐,这个时候可以使用 flask-sqlacodegen 来快速的生成model程序或者py文件,以下是简单的示例&a…

The module to import is incompatible with the current project【鸿蒙开发-BUG已解决】

文章目录 项目场景:问题描述原因分析:解决方案:心得体会:知识点OpenHarmony:HarmonyOS:项目场景: 报错: The module to import is incompatible with the current project 问题描述 希望通过 import module 将该模块引入到我的项目。 导入后出现错误,因为项目和模块…

【深入剖析K8s】容器技术基础(一):从进程开始说起

容器其实是一种特殊的进程而已。 可执行镜像 为了能够让这些代码正常运行’我们往往还要给它提供数据’比如我们这个加法程序所需要的输人文件这些数据加上代码本身的二进制文件放在磁盘上’就是我们平常所说的一个程序,也叫代码的可执行镜像(executablejmage&…

基于springboot实现实习管理系统的设计与实现项目【项目源码+论文说明】

基于sprinmgboot实现实习管理系统的设计与实现演示 摘要 随着信息化时代的到来,管理系统都趋向于智能化、系统化,实习管理也不例外,但目前国内仍都使用人工管理,市场规模越来越大,同时信息量也越来越庞大,…

力扣:180. 连续出现的数字(Python3)

题目: 表:Logs ---------------------- | Column Name | Type | ---------------------- | id | int | | num | varchar | ---------------------- 在 SQL 中,id 是该表的主键。 id 是一个自增列。 找出所有至少连续…

在服务器复用他人的anaconda3(免安装)

在服务器复用他人的anaconda3 1. 复制他人的anaconda3文件夹2. 修改配置文件3. 修改环境路径和包路径 1. 复制他人的anaconda3文件夹 cp -r /home/xxx/anaconda3 /home/your_username2. 修改配置文件 vim anaconda3/etc/profile.d/conda.sh # 替换原来的用户名为自己的用户名…

Pure-Pursuit 跟踪五次多项式轨迹

Pure-Pursuit 跟踪五次多项式轨迹 考虑双移线轨迹 X 轴方向位移较大,机械楼停车场长度无法满足 100 ~ 120 m,因此采用五次多项式进行轨迹规划,在轨迹跟踪部分也能水一些内容 调整 double_lane.cpp 为 ref_lane.cpp,结合 FrenetP…

Vue框架学习笔记——计算属性

文章目录 前文提要代码需求描述插值语法实现methods实现 计算属性getter执行时间:setter 计算属性简写形式(只读不改,才能如此简写)slice截取元素,限制输入字符数量 前文提要 本人仅做个人学习记录,如有错…

2023-11-22 LeetCode每日一题(网格中的最小路径代价)

2023-11-22每日一题 一、题目编号 2304. 网格中的最小路径代价二、题目链接 点击跳转到题目位置 三、题目描述 给你一个下标从 0 开始的整数矩阵 grid ,矩阵大小为 m x n ,由从 0 到 m * n - 1 的不同整数组成。你可以在此矩阵中,从一个…

Runloop解析

RunLoop 前言 ​ 本文介绍RunLoop的概念,并使用swift和Objective-C来描述RunLoop机制。 简介 ​ RunLoop——运行循环(死循环),它提供了一个事件循环机制在程序运行过程中处理各种事件,例如用户交互、网络请求、定…

Ansible的handler

环境 管理节点:Ubuntu 22.04控制节点:CentOS 8Ansible:2.15.6 handler 当任务结果产生变化时,通过 notify 通知handler做相应处理。 一个简单例子 --- - hosts: alltasks:- name: task1debug:msg: "I am task1"cha…

TCP/IP协议、三次握手、四次挥手

TCP/IP TCP/IP协议分层TCP头部三次握手TCP四次挥手常见问题1、什么是TCP网络分层2、TCP为什么是三次握手,不是两次或者四次?3、TCP为什么是四次挥手,为什么不能是三次挥手将第二次挥手和第三次挥手合并?4、四次挥手时为什么TIME_W…

seccomp学习 (3)

文章目录 0x06. 其他B. execveat (nr322)C. sendto recvfrom (nr44, 45)D. sendmsg recvmsg (nr46, 47)E. io_uring系列 (nr425,426,427) 本文继续上一篇文章继续介绍seccomp与系统调用的那些事~~~ 0x06. 其他 B. execveat (nr322) long sys_execveat(int dfd, const char…

python-opencv 人脸68点特征点检测

python-opencv 人脸68点特征点检测 不是很难,主要还是掉包,来看一下代码啊: # coding: utf-8 # 导包 import numpy as np import dlib import cv2class face_emotion(object):def __init__(self):# 人脸检测器对象,通过它拿到人…

C语言-内存函数详解

文章目录 1. memcpy使用和模拟实现2. memmove使用和模拟实现3. memset函数的使用4. memcmp函数的使用 1. memcpy使用和模拟实现 返回类型和参数: void * memcpy ( void * destination, const void * source, size_t num );1.函数memcpy从source的位置开始向后复制…

叠加原理(superposition principle)、线性系统

叠加原理(superposition principle):指对一个系统而言,两个或多个输入产生的输出,等于这几个输入单独引起的输出的和,即输入的叠加等于各输入单独引起的输出的叠加。 线性系统:一个系统&#x…

flutter 输入框组件 高度问题

使用的组件名字为 TestField 组件 TestField 配置 占位文字 设置 decoration 属性 InputDecoration 中hintText去掉输入到 输入框的间距 InputDecoration 中contentPadding EdgeInsets.zero去掉边框中的间距 InputDecoration 中 使用 isDense:true设置输入框内文字的颜色 …

Node.js 处理Mysql包含单引号字符字段

一、异步处理的方式 // 引入mysql模块const mysql require(mysql); // 创建数据库连接const connection mysql.createConnection({ host: localhost, user: your_username, password: your_password, database: your_database }); // 连接到数据库connection.conn…

go atexit源码分析

文章目录 atexit源码解析UML类图样例一: 程序退出之前执行注册函数1.1 流程图1.2 代码分析 样例二:使用cancel取消注册函数2.1 cancel流程图2.2 代码分析 样例三:使用Fatal/Fatalln/Fatal执行注册函数3.1 Fatal/Fatalln/Fatal流程图3.2 代码分析 atexit源…

02- OpenCV:加载、修改、保存图像

目录 1、加载图像(cv::imread) 2、显示图像 (cv::namedWindos 与cv::imshow) 3、修改图像 (cv::cvtColor) 4、保存图像(cv::imwrite) 5、代码演示 1、加载图像(cv::imread) cv::imread 是 OpenCV 库中用于读取图像文件的函数…
最新文章