解决js异步问题的方法--async和await(ES7)
2017-11-04 15:28
1121 查看
异步在给我们解决阻塞的问题时也带来一些别的问题
开发中调用接口经常是异步的,然后不小心就会犯的错误就是接口的数据还没有返回,我们就当作它已经返回了,然后继续处理,当然就会发生错误。
为了避免数据还没返回就继续执行,我们一般会在回掉函数里面继续些,但当层次多的时候不免会越来越乱,可读性别差
ES6引入promise函数处理异步问题,比之前好多了,但也并没有达到像写同步一样,ES7的两个新东西解决了这个问题,是我们像书写同步代码一样。
ES6-阮一峰:http://es6.ruanyifeng.com/#docs/promise (不懂promise的可以先看一下)
下面我会用我的理解,和容易让你明白的通俗的白话(其实是专业的也不会0.0)说明介绍一下async函数和await关键词(操作符)
上面的resolveAfter2Second(10)是一个异步函数(promise 对象写的 一会具体解释)
像这个一样 如果内部用异步函数 就在声明函数的时候用async关键字
await的作用就是等回调有了结果之后在执行下面的程序
看个例子
解读一下:
resolveAfter2Second()用setTimeout模拟一个异步请求,然后回调
如果没有async 和 await f1()函数会在等待resolveAfter2Second()时先执行console.log(x) 这是并不时我们想得到的
因为加了await 会 在resolveAfter2Second()函数有了返回结果后在执行下面的内容
所以看起来书写的方式和正常同步一样
看一下这个例子:
区别就是 await 写的位置不同,这会造成add1在5秒之后弹出结果,而add2会在7秒之后
add2 的 await写在resolveAfter2Second()前面,会在得到结果之后在执行下面的,所以是2S+5S,而add1的await写在a和b两个结果之前,是在a b得到值后在运行加法。
他们会像正常异步一样同时执行,所以只需要5s, 所以add1这种写法还是存在问题的
如果b的结果对a有影响b的用时较长,因此a的执行结果就有可能不正确,就和异步的问题一样。
总之就是加上async和await之后你就可以已正常方式书写了,不过因为必须会等待回调的结果 所以又可能会有等待(阻塞)的问题(没实际中使用,可能或许不会,如果错误请各位及时提醒,谢谢了)
还有一个问题就是这个是ES7的内容浏览器的兼容不是很好,现在chrome firefox opera都可以,但苹果的safari还不行,所以适当使用吧
个人粗略介绍,便于大家快速了解,具体的东西请看下面几篇文章:
http://es6.ruanyifeng.com/#docs/async
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/async_function
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/await
开发中调用接口经常是异步的,然后不小心就会犯的错误就是接口的数据还没有返回,我们就当作它已经返回了,然后继续处理,当然就会发生错误。
为了避免数据还没返回就继续执行,我们一般会在回掉函数里面继续些,但当层次多的时候不免会越来越乱,可读性别差
ES6引入promise函数处理异步问题,比之前好多了,但也并没有达到像写同步一样,ES7的两个新东西解决了这个问题,是我们像书写同步代码一样。
ES6-阮一峰:http://es6.ruanyifeng.com/#docs/promise (不懂promise的可以先看一下)
下面我会用我的理解,和容易让你明白的通俗的白话(其实是专业的也不会0.0)说明介绍一下async函数和await关键词(操作符)
async
如果你要写一个函数,里面包含有异步调用的函数,那么请你在定义这个函数之前加上async关键词async function f1 () { let x = await resolveAfter2Second(10) console.log(x) }
上面的resolveAfter2Second(10)是一个异步函数(promise 对象写的 一会具体解释)
像这个一样 如果内部用异步函数 就在声明函数的时候用async关键字
await
await 操作符用于等待一个Promise 对象await的作用就是等回调有了结果之后在执行下面的程序
看个例子
function resolveAfter2Second (x, time) { return new Promise(resolve => { setTimeout(() => { resolve(x) },time) }) } async function f1 () { let x = await resolveAfter2Second(10, 2000) console.log(x) } f1()
解读一下:
resolveAfter2Second()用setTimeout模拟一个异步请求,然后回调
如果没有async 和 await f1()函数会在等待resolveAfter2Second()时先执行console.log(x) 这是并不时我们想得到的
因为加了await 会 在resolveAfter2Second()函数有了返回结果后在执行下面的内容
所以看起来书写的方式和正常同步一样
function resolveAfter2Second (x, time) { return new Promise(resolve => { setTimeout(() => { resolve(x) }, time) }) } let add1 = async function (x) { let a = resolveAfter2Second(20, 2000) let b = resolveAfter2Second(30, 5000) return x + await a + await b } add1(10).then(res => { console.log('add1111', res) }) let add2 = async function (y) { let a = await resolveAfter2Second(20, 2000) let b = await resolveAfter2Second(30, 5000) return y + a + b } add2(100).then(res => { console.log('add22222', res) })
看一下这个例子:
区别就是 await 写的位置不同,这会造成add1在5秒之后弹出结果,而add2会在7秒之后
add2 的 await写在resolveAfter2Second()前面,会在得到结果之后在执行下面的,所以是2S+5S,而add1的await写在a和b两个结果之前,是在a b得到值后在运行加法。
let a = resolveAfter2Second(20, 2000) let b = resolveAfter2Second(30, 5000)
他们会像正常异步一样同时执行,所以只需要5s, 所以add1这种写法还是存在问题的
let b = resolveAfter2Second(30, 5000) let a = resolveAfter2Second(20, 2000)
如果b的结果对a有影响b的用时较长,因此a的执行结果就有可能不正确,就和异步的问题一样。
总之就是加上async和await之后你就可以已正常方式书写了,不过因为必须会等待回调的结果 所以又可能会有等待(阻塞)的问题(没实际中使用,可能或许不会,如果错误请各位及时提醒,谢谢了)
还有一个问题就是这个是ES7的内容浏览器的兼容不是很好,现在chrome firefox opera都可以,但苹果的safari还不行,所以适当使用吧
个人粗略介绍,便于大家快速了解,具体的东西请看下面几篇文章:
http://es6.ruanyifeng.com/#docs/async
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/async_function
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/await
相关文章推荐
- 利用async和await异步操作解决node.js里面fs模块异步读写,同步结果的问题
- 第二十三节: EF性能篇(三)之基于开源组件 Z.EntityFrameWork.Plus.EF6解决EF性能问题 第四节:一些指令总结 定时调度系列之Quartz.Net详解 第十七节:易混淆的概念(静态和非静态、拆箱和装箱) 那些年我们一起追逐的多线程(Thread、ThreadPool、委托异步调用、Task/TaskFactory、Parallerl、async和await)
- MVC5 新建项目里不包含jquery.unobtrusive-ajax.js(MVC5异步表单的问题)解决方法
- MVC5 新建项目里不包含jquery.unobtrusive-ajax.js(MVC5异步表单的问题)解决方法
- ReactNative踩坑日志——使用async/await语法解决网络请求的异步导致的指令执行顺序错乱问题
- ES7 中使用 async/await 解决回调函数嵌套问题
- JavaScript ES7 中使用 async/await 解决回调函数嵌套问题
- 数组方法解决JS字符串连接性能问题有争议
- 异步 HttpContext.Current实现取值的方法(解决异步Application,Session,Cache...等失效的问题)
- 【IE信息栏问题】本地html文件js被IE阻止的一些解决方法
- js escape,unescape解决中文乱码问题的方法
- JavaScript js 兼容浏览器问题 兼容FireFox(FF)、IE的解决方法
- vs2003 js文件编码问题的解决方法
- Asp.net页面中引用js文件无效的问题的解决方法
- 解决js jq跨子域无权限问题方法
- 【IE信息栏问题】本地html文件js被IE阻止的一些解决方法
- Asp.net页面中引用js文件无效的问题的解决方法
- 异步 HttpContext.Current实现取值的方法(解决异步Application,Session,Cache...等失效的问题)
- fireworks菜单生成器mm_menu.js在 IE 7.0 显示问题的解决方法
- 程序中和有js函数的网页交互,线程中调用 get_Script 就会错误的解决方法,由于COM的线程安全问题