Javascript中的async awai的用法
发布时间 - 2026-01-11 01:08:48 点击率:次async / await是ES7的重要特性之一,也是目前社区里公认的优秀异步解决方案。目前,async / await这个特性已经是stage 3的建议,可以看看TC39的进度,本篇文章将分享async / await是如何工作的,阅读本文前,希望你具备Promise、generator、yield等ES6的相关知识。

在详细介绍async / await之前,先回顾下目前在ES6中比较好的异步处理办法。下面的例子中数据请求用Node.js中的request模块,数据接口采用Github v3 api文档提供的repo代码仓库详情API作为例子演示。
Promise对异步的处理
虽然Node.js的异步IO带来了对高并发的良好支持,同时也让“回调”成为灾难,很容易造成回调地狱。传统的方式比如使用具名函数,虽然可以减少嵌套的层数,让代码看起来比较清晰。但是会造成比较差的编码和调试体验,你需要经常使用用ctrl + f去寻找某个具名函数的定义,这使得IDE窗口经常上下来回跳动。使用Promise之后,可以很好的减少嵌套的层数。另外Promise的实现采用了状态机,在函数里面可以很好的通过resolve和reject进行流程控制,你可以按照顺序链式的去执行一系列代码逻辑了。下面是使用Promise的一个例子:
const request = require('request');
// 请求的url和header
const options = {
url: 'https://api.github.com/repos/cpselvis/zhihu-crawler',
headers: {
'User-Agent': 'request'
}
};
// 获取仓库信息
const getRepoData = () => {
return new Promise((resolve, reject) => {
request(options, (err, res, body) => {
if (err) {
reject(err);
}
resolve(body);
});
});
};
getRepoData()
.then((result) => console.log(result);)
.catch((reason) => console.error(reason););
// 此处如果是多个Promise顺序执行的话,如下:
// 每个then里面去执行下一个promise
// getRepoData()
// .then((value2) => {return promise2})
// .then((value3) => {return promise3})
// .then((x) => console.log(x))
不过Promise仍然存在缺陷,它只是减少了嵌套,并不能完全消除嵌套。举个例子,对于多个promise串行执行的情况,第一个promise的逻辑执行完之后,我们需要在它的then函数里面去执行第二个promise,这个时候会产生一层嵌套。另外,采用Promise的代码看起来依然是异步的,如果写的代码如果能够变成同步该多好啊!
Generator对异步的处理
谈到generator,你应该不会对它感到陌生。在Node.js中对于回调的处理,我们经常用的TJ / Co就是使用generator结合promise来实现的,co是coroutine的简称,借鉴于python、lua等语言中的协程。它可以将异步的代码逻辑写成同步的方式,这使得代码的阅读和组织变得更加清晰,也便于调试。
const co = require('co');
const request = require('request');
const options = {
url: 'https://api.github.com/repos/cpselvis/zhihu-crawler',
headers: {
'User-Agent': 'request'
}
};
// yield后面是一个生成器 generator
const getRepoData = function* () {
return new Promise((resolve, reject) => {
request(options, (err, res, body) => {
if (err) {
reject(err);
}
resolve(body);
});
});
};
co(function* () {
const result = yield getRepoData;
// ... 如果有多个异步流程,可以放在这里,比如
// const r1 = yield getR1;
// const r2 = yield getR2;
// const r3 = yield getR3;
// 每个yield相当于暂停,执行yield之后会等待它后面的generator返回值之后再执行后面其它的yield逻辑。
return result;
}).then(function (value) {
console.log(value);
}, function (err) {
console.error(err.stack);
});
async / await对异步的处理
虽然co是社区里面的优秀异步解决方案,但是并不是语言标准,只是一个过渡方案。ES7语言层面提供async / await去解决语言层面的难题。目前async / await 在 IE edge中已经可以直接使用了,但是chrome和Node.js还没有支持。幸运的是,babel已经支持async的transform了,所以我们使用的时候引入babel就行。在开始之前我们需要引入以下的package,preset-stage-3里就有我们需要的async/await的编译文件。
无论是在Browser还是Node.js端都需要安装下面的包。
$ npm install babel-core --save $ npm install babel-preset-es2015 --save $ npm install babel-preset-stage-3 --save
这里推荐使用babel官方提供的require hook方法。就是通过require进来后,接下来的文件进行require的时候都会经过Babel的处理。因为我们知道CommonJs是同步的模块依赖,所以也是可行的方法。这个时候,需要编写两个文件,一个是启动的js文件,另外一个是真正执行程序的js文件。
启动文件index.js
require('babel-core/register');
require('./async.js');
真正执行程序的async.js
const request = require('request');
const options = {
url: 'https://api.github.com/repos/cpselvis/zhihu-crawler',
headers: {
'User-Agent': 'request'
}
};
const getRepoData = () => {
return new Promise((resolve, reject) => {
request(options, (err, res, body) => {
if (err) {
reject(err);
}
resolve(body);
});
});
};
async function asyncFun() {
try {
const value = await getRepoData();
// ... 和上面的yield类似,如果有多个异步流程,可以放在这里,比如
// const r1 = await getR1();
// const r2 = await getR2();
// const r3 = await getR3();
// 每个await相当于暂停,执行await之后会等待它后面的函数(不是generator)返回值之后再执行后面其它的await逻辑。
return value;
} catch (err) {
console.log(err);
}
}
asyncFun().then(x => console.log(`x: ${x}`)).catch(err => console.error(err));
注意点:
- async用来申明里面包裹的内容可以进行同步的方式执行,await则是进行执行顺序控制,每次执行一个await,程序都会暂停等待await返回值,然后再执行之后的await。
- await后面调用的函数需要返回一个promise,另外这个函数是一个普通的函数即可,而不是generator。
- await只能用在async函数之中,用在普通函数中会报错。
- await命令后面的 Promise 对象,运行结果可能是 rejected,所以最好把 await 命令放在 try...catch 代码块中。
其实,async / await的用法和co差不多,await和yield都是表示暂停,外面包裹一层async 或者 co来表示里面的代码可以采用同步的方式进行处理。不过async / await里面的await后面跟着的函数不需要额外处理,co是需要将它写成一个generator的。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# js中的await
# async
# js
# await
# async用法
# JavaScript中使用Async实现异步控制
# async/await与promise(nodejs中的异步操作问题)
# JavaScript无阻塞加载和defer、async详解
# JavaScript中的await/async的作用和用法
# 关于Javascript中defer和async的区别总结
# JS中script标签defer和async属性的区别详解
# 浏览器环境下JavaScript脚本加载与执行探析之defer与async特性
# 理解javascript async的用法
# 多个
# 放在
# 是一个
# 回调
# 很好
# 返回值
# 这个时候
# 链式
# 后会
# 用在
# 的是
# 都是
# 层数
# 是在
# 还没有
# 你可以
# 第一个
# 多好
# 就有
# 不需要
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
香港服务器部署网站为何提示未备案?
Python3.6正式版新特性预览
Laravel用户认证怎么做_Laravel Breeze脚手架快速实现登录注册功能
Laravel如何配置和使用缓存?(Redis代码示例)
Laravel如何处理CORS跨域请求?(配置示例)
瓜子二手车官方网站在线入口 瓜子二手车网页版官网通道入口
Laravel如何使用Blade模板引擎?(完整语法和示例)
历史网站制作软件,华为如何找回被删除的网站?
美食网站链接制作教程视频,哪个教做美食的网站比较专业点?
Laravel怎么配置S3云存储驱动_Laravel集成阿里云OSS或AWS S3存储桶【教程】
高配服务器限时抢购:企业级配置与回收服务一站式优惠方案
Python函数文档自动校验_规范解析【教程】
如何快速搭建个人网站并优化SEO?
Laravel如何编写单元测试和功能测试?(PHPUnit示例)
php在windows下怎么调试_phpwindows环境调试操作说明【操作】
宙斯浏览器怎么屏蔽图片浏览 节省手机流量使用设置方法
北京网站制作的公司有哪些,北京白云观官方网站?
香港服务器租用每月最低只需15元?
详解免费开源的DotNet二维码操作组件ThoughtWorks.QRCode(.NET组件介绍之四)
三星网站视频制作教程下载,三星w23网页如何全屏?
教学论文网站制作软件有哪些,写论文用什么软件
?
标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等?
动图在线制作网站有哪些,滑动动图图集怎么做?
JS实现鼠标移上去显示图片或微信二维码
laravel怎么为应用开启和关闭维护模式_laravel应用维护模式开启与关闭方法
Laravel如何实现多表关联模型定义_Laravel多对多关系及中间表数据存取【方法】
如何在云服务器上快速搭建个人网站?
无锡营销型网站制作公司,无锡网选车牌流程?
东莞专业网站制作公司有哪些,东莞招聘网站哪个好?
Win11摄像头无法使用怎么办_Win11相机隐私权限开启教程【详解】
黑客如何通过漏洞一步步攻陷网站服务器?
Laravel怎么在Controller之外的地方验证数据
如何在浏览器中启用Flash_2025年继续使用Flash Player的方法【过时】
如何用AI一键生成爆款短视频文案?小红书AI文案写作指令【教程】
阿里云网站搭建费用解析:服务器价格与建站成本优化指南
Swift中swift中的switch 语句
百度输入法全感官ai怎么关 百度输入法全感官皮肤关闭
如何挑选优质建站一级代理提升网站排名?
Laravel怎么返回JSON格式数据_Laravel API资源Response响应格式化【技巧】
Laravel怎么解决跨域问题_Laravel配置CORS跨域访问
Laravel模型事件有哪些_Laravel Model Event生命周期详解
香港服务器建站指南:外贸独立站搭建与跨境电商配置流程
香港服务器网站卡顿?如何解决网络延迟与负载问题?
Win11怎么设置虚拟桌面 Win11新建多桌面切换操作【技巧】
如何在 Go 中优雅地映射具有动态字段的 JSON 对象到结构体
Laravel如何处理跨站请求伪造(CSRF)保护_Laravel表单安全机制与令牌校验
Laravel如何使用Facades(门面)及其工作原理_Laravel门面模式与底层机制
网站制作价目表怎么做,珍爱网婚介费用多少?
Laravel如何使用软删除(Soft Deletes)功能_Eloquent软删除与数据恢复方法
Laravel如何使用Gate和Policy进行授权?(权限控制)

