关灯
首页
论坛首页
大咖专栏
大咖专栏
热点资讯
热点资讯
精彩活动
精彩活动
关于
关于
本版
文章
帖子
用户
登录
注册
快捷登录
投稿
EOIT论坛
›
社区交流
›
WEB前端
›
怎样处理async/await浪费性能问题
返回列表
怎样处理async/await浪费性能问题
[复制链接]
老蚊子
发表于 2019-1-23 09:08:39
|
显示全部楼层
|
阅读模式
这次给大家带来怎样处理async/await浪费性能问题,处理async/await浪费性能问题的注意事项有哪些,下面就是实战案例,一起来看一下。
前言
async/await是什么
async/await可以说是co模块和生成器函数的语法糖。用更加清晰的语义解决js异步代码。
熟悉co模块的同学应该都知道,co模块是TJ大神写的一个使用生成器函数来解决异步流程的模块,可以看做是生成器函数的执行器。而async/await则是对co模块的升级,内置生成器函数的执行器,不再依赖co模块。同时,async返回的是Promise。
从上面来看,不管是co模块还是async/await,都是将Promise作为最基础的单元,对Promise不很了解的同学可以先深入了解一下Promise。
async/await 写着很爽,不过要注意这些问题。
async/await 让我们摆脱了回调地狱,但是这又引入了 async/await 地狱的问题。
什么是 async/await 地狱
在 Javascript 中进行异步编程的时候,人们总是使用很多 await 语句,很多时候我们的语句并不需要依赖于之前的语句,这样就会导致性能问题。
async/await 地狱的例子
我们试着写一个购买披萨和饮料的程序:
(async () => {
const pizzaData = await getPizzaData() // async call
const drinkData = await getDrinkData() // async call
const chosenPizza = choosePizza() // sync call
const chosenDrink = chooseDrink() // sync call
await addPizzaToCart(chosenPizza) // async call
await addDrinkToCart(chosenDrink) // async call
orderItems() // async call
})()
复制代码
这段代码运行没有问题。但是不是一个好的实现,因为这增加了不必要的等待。
说明
我们已经将我们的代码封装在异步 IIFE 中,按照下面的顺序执行:
得到披萨名单
获取饮料列表
从列表中选择一个披萨
从列表中选择一种饮料
将选中的披萨加入购物车
将选择的饮品加入购物车
订购购物车中的物品
问题
这里有个问题为什么从列表中选择披萨这个动作要等待获取饮料列表?这两个是没什么关联的操作。其中的关联操作有两组:
获取披萨列表 -》 选择披萨 -》 选择披萨加入购物车
获取饮料列表 -》 选择饮料 -》 选择饮料加入购物车
这两组操作应该是并发执行的。
再来看一个更差的例子
这个 Javascript 代码片段将购物车中的商品并发出订购请求。
async function orderItems() {
const items = await getCartItems() // async call
const noOfItems = items.length
for(var i = 0; i < noOfItems; i++) {
await sendRequest(items[i]) // async call
}
}
复制代码
这种情况 for 循环必须等待 sendRequest() 函数完成才能继续下一次迭代。但是,我们并不需要等待。我们希望尽快发送所有请求。然后我们可以等待所有请求完成。
现在你应该已经对 async/await 地狱有跟多的了解,现在我们再来考虑一个问题
如果我们忘记 await 关键字会怎么样?
如果在调用异步函数忘记使用 await,这意味着执行该功能不需要等待。异步函数将直接返回一个 promise,你可以稍后使用。
(async () => {
const value = doSomeAsyncTask()
console.log(value) // an unresolved promise
})()
复制代码
或者是程序不清楚你想要等待函数执行完,直接退出不会完成这个异步任务。所以我们需要使用 await 这个关键字。
promise 有一个有趣的属性,你可以在某行代码中获取 promise,然后在其他地方中等待它 resolve,这是解决 async/await 地狱的关键。
(async () => {
const promise = doSomeAsyncTask()
const value = await promise
console.log(value) // the actual value
})()
复制代码
如你所见 doSomeAsyncTask 直接返回一个 Promise 同时这个异步函数 doSomeAsyncTask 已经开始执行,为了得到 doSomeAsyncTask 的返回值,我们需要 await 来告诉
应该如何避免 async/await 地狱
首先我们需要知道哪些命名是有前后依赖关系的。
然后将有依赖关系的系列操作进行分组合并成一个异步操作。
同时执行这些异步函数。
我们来重写这写例子:
async function selectPizza() {
const pizzaData = await getPizzaData() // async call
const chosenPizza = choosePizza() // sync call
await addPizzaToCart(chosenPizza) // async call
}
async function selectDrink() {
const drinkData = await getDrinkData() // async call
const chosenDrink = chooseDrink() // sync call
await addDrinkToCart(chosenDrink) // async call
}
(async () => {
const pizzaPromise = selectPizza()
const drinkPromise = selectDrink()
await pizzaPromise
await drinkPromise
orderItems() // async call
})()
// Although I prefer it this way
(async () => {
Promise.all([selectPizza(), selectDrink()].then(orderItems) // async call
})()
复制代码
我们将语句分成两个函数。在函数内部,每个语句都依赖于前一个语句的执行。然后我们同时执行这两个函数 selectPizza()和selectDrink() 。
在第二个例子中我们需要处理未知数量的 Promise。处理这个问题非常简单,我们只需要创建一个数组将所有 Promise 存入其中,使用 Promise.all() 方法并行执行:
async function orderItems() {
const items = await getCartItems() // async call
const noOfItems = items.length
const promises = []
for(var i = 0; i < noOfItems; i++) {
const orderPromise = sendRequest(items[i]) // async call
promises.push(orderPromise) // sync call
}
await Promise.all(promises) // async call
}
复制代码
以上就是怎样处理async/await浪费性能问题的详细内容。
回复
举报
返回列表
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
本版积分规则
发表回复
回帖并转播
回帖后跳转到最后一页
老蚊子
版主
1
关注
13
粉丝
75
帖子
发送私信
收听TA
Ta的主页
热门图文
微信小程序插件系列(一)日历插件
中国平安产品经理和app开发打架视频事件始
如何有效的学习Web前端开发?
微信小程序-音乐播放器详解
如何从零开始学Java
零基础小白如何学习UI设计
热门帖子
WEB前端
微信小程序插件系列(一)日历插件
新手报到
中国平安产品经理和app开发打架视频事件始
新手报到
报道贴
WEB前端
如何有效的学习Web前端开发?
WEB前端
微信小程序-音乐播放器详解
Java大数据
如何从零开始学Java
UI设计
零基础小白如何学习UI设计
WEB前端
常见的js设计模式,面试必备
排行榜
日
周
月
1
百杰197开班啦!~~~
百杰197部开班啦!~~~ 方向:web
159
0
2
✿✿✿国信安教育百杰191部测试班级信息✿
✿✿✿国信安教育百杰191部测试班级信息✿✿✿ 班 级:百杰191部 专业方向:软件测
159
1
3
国信安教育百杰195部前端班
✿✿✿国信安教育百杰195部前端班级信息✿✿✿ 班 级:百杰w195部 专业方向:web
139
0
4
html中如何让文字竖排
在写网页时,为了让页面好看,可能会考虑使用竖排文字,在使用时发现不简单.第一种:原始
146
0
5
可查询每个时代流行配色组合的Color Leap
每个时代都有代表的文化和呈现样貌,如果对于一些绘画或摄影作品有研究,可能也会发现
154
0
6
设计页面单薄,如何提升质感?
质感是什么?如何让画面拥有更高端的质感?本文由质感的原理出发,深入分析质感表现所
184
0
7
面型图标vs线型图标,哪一种的用户体验会更
什么时候该用线型图标,什么时候该用面型图标,不知道大家平时有没有去思考过?我自己
148
0
8
193JAVA开班了
看过来,193的哥哥姐姐们。
203
0
9
js中 ECMAScript位运算符
ECMAScript位运算符: https://blog.csdn.net/qwlzxx/article/details/46669985 摘抄
170
0
10
UI布局中颜色的使用原理
色彩在GUI的交互中扮演着重要的角色。合理的使用颜色,能帮助用户快捷的发现界面中的
172
0
1
微信小程序插件系列(一)日历插件
近期有玩小程序的朋友问我在小程序中如何引用插件。那么近期就给大家推荐几款实用的微
8539
1
2
中国平安产品经理和app开发打架视频事件始
据爆料,中国平安一个产品经理和APP开发人员在办公室直接打起来了,据称是产品经理向A
6609
2
3
如何有效的学习Web前端开发?
一个好的Web前端工程师在知识体系上既要有广度,又要有深度,所以很多大公司即使出高
4487
8
4
微信小程序-音乐播放器详解
大家好,上一篇分享了如何获取酷狗的音乐资源,今天给大家聊一下微信小程序中音
4378
2
5
如何从零开始学Java
虽然Java面象对象很多东西都是被封装好的直接用,相对其他语言没那么复杂,但是学的东
3417
1
6
零基础小白如何学习UI设计
用户体验至上的时代已经来临。能够吸引到用户的界面,都是UI设计师的精心设计的功劳。
3350
4
7
常见的js设计模式,面试必备
每个JS开发者都力求写出可维护、复用性和可读性高的代码。随着应用不断扩大,代码组织
3333
19
8
常用酷狗音乐资源接口
这几天在大学带小朋友们玩微信小程序,有的学生不知道如何获取到音乐资源,今天
3331
4
9
论坛攻略-----如何获得积分与安仔币、快速
国信安论坛——EOIT上线啦!!!赶快来玩转论坛,获取积分,领取礼品哟!!! 积分与
3180
0
10
国信安教育百杰☆☆☆就业信息☆☆☆
国信安教育2018年学员就业信息展示——你也可以像他们一样拿高薪哦!!!
3123
16
1
百杰197开班啦!~~~
百杰197部开班啦!~~~ 方向:web
159
0
2
✿✿✿国信安教育百杰191部测试班级信息✿
✿✿✿国信安教育百杰191部测试班级信息✿✿✿ 班 级:百杰191部 专业方向:软件测
159
1
3
国信安教育百杰195部前端班
✿✿✿国信安教育百杰195部前端班级信息✿✿✿ 班 级:百杰w195部 专业方向:web
139
0
4
html中如何让文字竖排
在写网页时,为了让页面好看,可能会考虑使用竖排文字,在使用时发现不简单.第一种:原始
146
0
5
可查询每个时代流行配色组合的Color Leap
每个时代都有代表的文化和呈现样貌,如果对于一些绘画或摄影作品有研究,可能也会发现
154
0
6
设计页面单薄,如何提升质感?
质感是什么?如何让画面拥有更高端的质感?本文由质感的原理出发,深入分析质感表现所
184
0
7
面型图标vs线型图标,哪一种的用户体验会更
什么时候该用线型图标,什么时候该用面型图标,不知道大家平时有没有去思考过?我自己
148
0
8
193JAVA开班了
看过来,193的哥哥姐姐们。
203
0
9
js中 ECMAScript位运算符
ECMAScript位运算符: https://blog.csdn.net/qwlzxx/article/details/46669985 摘抄
170
0
10
UI布局中颜色的使用原理
色彩在GUI的交互中扮演着重要的角色。合理的使用颜色,能帮助用户快捷的发现界面中的
172
0
作者专栏
750
刘大阳
200
大菲
161
安仔
139
意大利炮
114
小川
84
丘丘
关闭
站长推荐
/1
论坛攻略-----如何获得积分与安仔币、快速升级
国信安论坛——EOIT上线啦!!!赶快来玩转论坛,获取积分,领取礼品哟!!!
查看 »
快速回复
返回顶部
返回列表