什么是异步
在了解异步的的前面我们要了解一个东西。javascript
运行机制是单线程,即一般情况下都是一个个的执行,如果遇到多种情况一起来,只能排队。这种就叫同步
。
这样就会导致一个情况。如果前者的任务的执行时间特别长,导致后面某些任务无法执行。造成页面假死。这种体验一般来说都很糟糕。这样就需要用到异步
最简单的异步模式
js对于异步的处理,很多人的第一反应是ajax,这只能说是对了一半。我感觉setTimeout
和setInterval
算是最早的js实现异步模式了。
这里举个简单的例子一笔带过1
2
3
4
5
6
7
8
9
10
11
12
13
14
let zone=()=>{
console.log(1)
setTimeout(()=>{
console.log(2)
},1000)
setTimeout(()=>{
console.log(3)
},0)
console.log(4)
}
zone()
结果很显而易见。这里不做过多说明
不过这里说一下setTimeout
不带参数和参数为0的区别。
- 参数为0,其实就相当于一个
callback
回调函数。相当于插队,等上一个程序执行完,就立刻执行这个程序。 - 不带参数。一般就是放置在末尾最后处理
优点:
- 最简单的回调
缺点
- 容易造成回调地狱。
- 比较Low
Promise
看过ES6
的基本上都知道这个东西了。差不多就是专门用于解决异步相关的问题,两个方法then
和catch
,then
方法第一个参数是resolve状态时执行的回调,第二个参数则是reject状态时执行的回调,而catch则是then
中有一环是reject
就执行的回调函数。三个状态pending(进行中)
, fulfilled(已完成)
, rejected(已失败)
一个简单的promise
1 | var promise=new Promise(function(resove,reject){ |
Promise实例生成以后,可以用then方法分别指定resolved
状态和reject
状态的回调函数。
比如这个例子1
2
3
4
5
6
7
8
9
10let promise=new Promise(function(resolve,reject){
console.log('说点什么好呢');
setTimeout(()=>{
resolve();
},1000)
})
promise.then(function(){
console.log('我后执行')
})
console.log('三大赵日天')
这里结果很明显,第一次声明promise对象的时候,会执行一遍。
所以”说点什么好呢”第一,然后输出”三大赵日天”,一秒之后 promise
的状态由pending
变为resolve
出发then
之后的回调。一些复杂的用法可以去看看阮一峰的介绍。这里我也记不清楚。
ES8的async
其实promise
已经足够我们应付一些简单的业务需求的了。但是面对多重调用的promise
方法,也会出现一些问题。例如1
2
3
4
5
6
7
8
9
10
promise.then(db=> {
return promiseB(db);
}).then(coll=> {
return promiseC(coll);
}).then(blogs=> {
console.log(blogs;
}).catch(err=> {
console.log(err);
})
虽然在这个Promise链上,如果任何一个环节出现异常,都会被最后的catch()捕捉到。比起层层回调会显得稍微好点,但是有一点不是很好,这里的then()方法获取的对象,都是上一个方法返回的对象。这样而且还不能跨层访问。
这时候就需要用到async
还是直接上代码举个例子1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20var sleep = function (time) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve();
}, time);
})
};
var zone=sleep(2000).then(()=>{
console.log("三大赵日天");
return sleep(2000)
}).then(()=>{
console.log("三大赵日天")
return sleep(2000)
}).then(()=>{
console.log("三大赵日天")
})
这样基本上就实现了 每隔两秒输出一次"三大赵日天"
显然这样是不够优雅的。虽然不Low
如果用async
会怎么样呢?
1 | var sleep = function (time) { |
其实 async
感觉就是promise
的拓展版,用了同步的实现去实现异步。只不过async
没有then
和catch
,捕获异常是用的try catch
。实现起来也很简单。
这里对上面代码做点加工1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20var sleep = function (time) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
reject("出错啦");
}, time);
})
};
var zone=async function(){
try{
console.log("开始了")
await sleep(2000);
console.log("三大赵日天")
await sleep(2000)
console.log("三大赵日天")
} catch(res){
console.log("出错了",res)
}
}
zone();
基本上常见的JS实现异步的方法。上面几种平时处理一般业务逻辑也够用了。感觉平时学习预期多背框架API 还不如抽时间弄明白一些基础的原理。这样后面学习新的框架的时候也能很快适应。。有些原理弄明白之后,框架自然也就熟悉API了。去年有人问过我promise
那时候还只会背背API。照着别人模子套。这段时间看async
查了查资料 总算能明白点大概 也算有点进步了。。