大家都知道Js是一门单线程的语言,所以异步执行是Js的非常重要的一点,可以说没有异步Js根本没法用,非卡死不可。
以前实现异步编程,我们一般是通过回调函数,但是后来发现,当异步操作之间有着依赖关系特别是这种依赖关系的层级非常多之后,再去用这种回调函数的方法去实现实在是一场噩梦,太不方便了很容易出错又不好看,也就是我们常说的回调函数地狱(callback hell),
function load(){
setTimeout(function(){
setTimeout(function(){
setTimeout(function(){
.....
},1000)
},1000)
},1000)
}
后来为了解决这个问题es6推出了一个新概念叫Promise,关于这个新特性可以看我之前的文章,里面把常用的几个方法基本都讲了。
其实主要就是把原来的回调函数的写法改的看上去比较像同步的写法。就像这样:
function run(){
var load = new Promise(function(res,rej){
setTimeout(function(){...},1000)
})
return load;
}
function run2(){
var load = new Promise(function(res,rej){
setTimeout(function(){...},1000)
})
return load;
}
run().then(function(){
return run2()
}).then(function(){
...
})
虽然看上去好像更复杂了,但是其实是使多层异步函数的写法更简便了。
但是这样也并没有让所有人都满意,他们觉得用这种方式then太多了语义化不明显,代码流程不能很好的表示执行流程。
于是就有了async/await
这种方式的写法其实也是基于promise的
function run(){
var load = new Promise(function(res,rej){
setTimeout(function(){
res('haha')
},1000)
})
return load;
}
function run2(){
var load = new Promise(function(res,rej){
setTimeout(function(){
res('nihao')
},1000)
})
return load;
}
async function all(){
var x = await run() //x='haha' //await会导致 function all 暂停执行
var y = await run2() //y='nihao'
...
}
all()
console.log(1) //这句会最先执行
这种方式看的才更像是同步的。
从字面意思上看await就是等待,await 等待的是一个表达式,这个表达式的返回值可以是一个promise对象也可以是其他值。但是其他值的话肯定是同步执行的也就没有这样写的必要了。
需要注意的是只有在async声明的函数下才能使用await
await后面可以跟Promise对象或者不是Promise但是一般建议跟Promise对象,否则没意义。
await 在等待 Promise 对象时会导致 async function 会暂停执行, 一直到 Promise 对象决议(队列中的同步代码执行完毕)之后才会 async function
继续执行.
async 定义的是异步函数 该函数的返回值很特殊: 不管在函数体内 return
了什么值, async
函数的实际返回值总是一个 Promise
对象.
async function run(){
return 1
}
run().then(res=>{
console.log(res) //1
})
这种写法的返回值也是Promise这个1会在函数执行后的then函数中一参数形式出现.
关于async/await的还有很多讲,这次就先到这吧。下次会讲一下async/await的执行顺序,喜欢的小伙伴可以关注一下哦。