您的位置:首页 > Web前端 > JavaScript

解决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关键词(操作符)

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐