关于async await

async await于ES2017标准引入,本身的功能是作为语法糖简化写法的。

下面列举一个使用promise的例子:

 function myPromise(flag) {
     return new Promise((resolve, reject) => {
         if (flag) {
             return resolve(flag)
         } else {
             return reject('error')
         }
     })
 }
 // 在p1的回调调用p2
 const p1 = myPromise(1)
 p1.then(v => {
     const p2 = myPromise(2)
     p2.then(v => {
         console.log(v)
     })
 })

因为p2的参数与p1的返回值有关这个例子确保了p2在p1的promise为成功的情况下再调用,确保了调用的顺序,如果只有少许的顺序要求,实现起来结构还不至于非常复杂,如果后续需要确保多个promise的调用顺序,那么就会有很多层.then去调用promise会导致代码嵌套太多,可读性差。

async await的出现解决了代码可读性的问题。

下面是一个例子:

 function myPromise(flag) {
     return new Promise((resolve, reject) => {
         if (flag) {
             return resolve(flag)
         } else {
             return reject('error')
         }
     })
 }
 let v
 const p1 = await myPromise(1)
 p1.then(val => { v = val }) 
 const p2 = await myPromise(v)
 p2.then(val => { v = val })
 const p3 = await myPromise(v)
 p3.then(val => { v = val })
 const p4 = await myPromise(v)
 p4.then(val => { v = val })
 const p5 = await myPromise(v)
 p5.then(val => { v = val })
 const p6 = await myPromise(v)
 p6.then(val => { v = val })
 const p7 =  myPromise(v)

这样就可以不依靠大量的.then嵌套去确保异步方法的调用顺序。

效率问题的思考

下面给大家看一段伪代码:

 function getData(url) {
     return url
 }
 ​
 function postData(url) {
     console.log(url)
 }
 ​
 let data1 = await getData('/xxx') // 操作1 需要花费10s
 let data2 = await getData('/xxx') // 操作2 需要花费10s
 postData(data1   '/xxx') // 操作3 需要花费20s
 postData(data2   '/yyy') // 操作4 需要花费5s

熟悉js事件循环的同学应该能很快求出执行所需的时间,总共需要40s去执行,那么对于这个伪代码我们可以做出优化吗?答案是可以的。

下面看一下优化后的代码:

 function getData(url) {
     return url
 }
 ​
 function postData(url) {
     console.log(url)
 }
 ​
 let data1 = await getData('/xxx') // 操作1 需要花费10s
 postData(data1   '/xxx') // 操作4 需要花费20s
 let data2 = await getData('/xxx') // 操作2 需要花费10s
 postData(data2   '/yyy') // 操作3 需要花费5s

这样的话执行时间就被优化到了30s,我们可以看一下二者的执行时的对比:

第一个方式

第二个方式

所以当我们使用async await时还是要去注意一下异步代码的调用顺序,适当的优化可以减少程序的运行时间,而且我们应正确的使用async await语法糖,只有后续操作需要用到异步请求所得到的数据时才需要为异步请求加上await修饰确保数据能够获取,否则不需要加await修饰。

后续

虽然可能大家觉得这个题目比较标题党,但我没有要深度剖析的意思,只是想交流讨论一下,希望大家的评论还是客气一点。 关于评论区有掘友指出我的理解有问题,这里我用setTimeout控制一下Promise的返回时间,代码如下

function t5s() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(1)
            console.log('5s')
        }, 5000);
    })
}
function t3s() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(1)
            console.log('3s')
        }, 3000);
    })
}
function t2s() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(1)
            console.log('2s')
        }, 2000);
    })
}
/* 
    这里应该是等待5s后返回第一个Promise并打印5s,然后再等待3s后返回第二个Promise并打印3s,
    最后再等待2s后返回第三个Promise并打印2s,总用时10s
*/
(async () => {
    await t5s()
    await t3s()
    await t2s()
})()
/*
    这里我的理解是3个操作会依次进入微任务池中依次执行,因此2s后打印2s,3s后打印3s,5s后打印5s,总用时5s
*/
(() => {
    t5s()
    t3s()
    t2s()
})()

总结

到此这篇关于对async await效率问题的深入思考的文章就介绍到这了,更多相关async await效率问题内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

关于对async await效率问题的深入思考的更多相关文章

  1. iOS:核心图像和多线程应用程序

    我试图以最有效的方式运行一些核心图像过滤器.试图避免内存警告和崩溃,这是我在渲染大图像时得到的.我正在看Apple的核心图像编程指南.关于多线程,它说:“每个线程必须创建自己的CIFilter对象.否则,你的应用程序可能会出现意外行为.”这是什么意思?我实际上是试图在后台线程上运行我的过滤器,所以我可以在主线程上运行HUD(见下文).这在coreImage的上下文中是否有意义?

  2. UIWebView stringByEvaluatingJavaScriptFromString在使用GCD调用时挂在iOS5.0 / 5.1上

    我在viewDidLoad中有以下代码,它在iOS4.3上正常工作,但它挂在iOS5/5.1上.在iOS5/5.1上,显示警告对话框,但无法关闭,UI线程冻结,OK按钮无法单击.这是一个bug吗?解决方法经过测试,我认为它是一个Bug,并改变使用的代码会解决

  3. ios – iPhone:一段时间后,所有动画都停止工作

    我最近有一些奇怪的行为.所有动画有时会突然停止工作.有时候一切顺利,其他时候就会发生.推送和弹出视图只是捕捉到位,UITableViewcellrow动画不起作用.该应用程序使用了很多后台线程,所以也许有东西在那里?我不能真正发布代码,因为我不知道问题在哪里.有人有同样的问题吗?解决方法你可以尝试在不同的后台线程中更新UI/animate吗?

  4. ios – 在后台线程上创建一个视图,在主线程中添加主视图

    我是C的新来的,来自.NET和java背景.所以我需要异步地创建一些UIwebviews,我在自己的队列中使用这个因为你会想象这会引发错误:那么如何在主线程上添加子视图?

  5. 在iOS模拟器上显示GMSMarkers时发生GMSThreadException

    我正在开发一个应用程序,在GMSMapView上显示大约200个GMSMarkers我尝试了2种方法来显示标记.Method1有点慢,但没有错误发生,但是,Method2在真实设备上运行顺畅但我在iOS模拟器上测试它时得到了GMSThreadException以下是问题:1.继续使用method2可以吗?任何帮助是赞赏OrzUPDATE1正如@ztan在下面回答的那样,我必须在主线程中完成所有这些,有没有比这更好的解决方案?

  6. ios – 在分离的线程问题中使用块的异步FB请求

    我正在使用IOSFacebookSDK3,我正在尝试使用更高效的方法.所以我想在单独的线程中管理一些请求.例如这个请求:>我正在使用这个在我的Feed上发布内容,我调用一个方法来自动加载此请求的内容,然后在方法中调用此块以启动请求.这个很好用.>问题是如果我不将此请求放在一个块中,那就不起作用了.此请求不起作用我想弄清楚,但我不明白是什么问题.在此先感谢您的帮助.解决方法我有一点这个问题.确保在主线程上分派代码.

  7. ios – UIAlertController有时会阻止UIRefreshControl隐藏

    编辑:这是我在代码中创建刷新控件的方法:解决方法我相信它真的与tableView在UIAlertController呈现之前没有滚动回来有关.我试图设置showUpdateInfo方法的延迟,这似乎有效.我猜当用户只拉一次它需要半秒钟来显示UIAlertController检查是否有帮助.这是我的代码如果有帮助,请告诉我.

  8. 在Swift中应用Grand Central Dispatch(上

    在这两篇教程中,你会学到GCD的来龙去脉。起步libdispatch是Apple所提供的在IOS和OSX上进行并发编程的库,而GCD正是它市场化的名字。Swift中的闭包和OC中的块类似甚至于他们几乎就是可交换使用的。但OC中的块可以安全的替换成Swift中的闭包。再一次,这完全取决于GCD。QoS等级表示了提交任务的意图,使得GCD可以决定如何制定优先级。QOS_CLASS_USER_INteraCTIVE:userinteractive等级表示任务需要被立即执行以提供好的用户体验。

  9. 转 Grand Central Dispatch 基础教程:Part 1/2 -swift

    第一节将解释什么是GCD并了解几个GCD的基础函数。GettingStartedGCD是libdispatch的代名词,libdispatch代表着运行iOS与OSX的多核设备上执行并行代码的官方代码库。再有一点要记住的就是在任何GCD文档中涉及到Objective-C的块代码都是可以用Swift的闭包来替换的。举个具有线性安全性的代码示例leta=["thread-safe"]。因为,这一切都是由GCD控制的。任务的开始执行的时间完全由GCD决定。它也是唯一一个用作向UIView对象发送信息或推送监听。

  10. Swift之dispatch_source实现多线程定时关闭功能

    由于在项目中需要用到定时关闭音频功能,本来打算用NSTimer的,可是写起来并不是那么精简好用,所以又在网上找到相关的实例,结合自己项目需要,就写出了如下代码,还请大家指教,废话不多说:

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部