目前学前端已经两个半月,在学一个月后有幸能够跟导师做项目,在一个月前刚开始做的时候,很迷茫,尤其是在把自己学到的东西付诸实践的时候,索性项目不难一周就能够完成大多数功能,我采用vuex来处理父子组件传值问题,在与后端交互数据的时候,不可避免的有异步处理问题,前面这一百多字可以忽略,接下来就是我对异步处理的理解。
当我刚开始做项目的时候,处理异步的方式极其丑陋,用的计时器回调函数的方式处理的,而后来在读《你不知道的js》的时候发现了一篇(中卷的第二部分)讲到异步,犹如发现了新大陆,处理异步的几种ES5及之前的方式:
回调函数、事件监听(观察者模式),在学nodejs的时候对node中的Emitter API有一些了解,通过emit 提交事件 on监听事件,而回调函数则是在异步完成后执行回调函数达到异步效果。
ES6中的Promise更加强大,他也是通过回调函数,不过Promise的异步处理有相当于回调函数和事件监听的组合,他通过不同状态来执行不同的回调,不知道你有没有看过Promise的源码,他的then方法时有一个异步处理的(把then处理成异步),我在第一次看到把then处理成异步的时候就很疑惑这样做有什么用?
let p = new Promise((resolve,reject) => {
console.log('p')
setTimeout(() => {
resolve('11')
},100)
})
let p1 = new Promise((resolve, reject) => {
console.log('p1')
setTimeout(() => {
resolve('22')
},1000)
})
let pp = Promise.resolve('1');
pp.then(data => {
console.log(data)
}).then(() => {
return new Promise((resolve, reject) => {
console.log('p1')
setTimeout(() => {
resolve('22')
},1000)
});
}).then(data => {
console.log(data)
})
pp.then(data => {
console.log(data)
}).then(() => {
return new Promise((resolve,reject) => {
console.log('p')
setTimeout(() => {
resolve('11')
},100)
});
}).then(data => {
console.log(data)
})
p
p1
1
1
11
22
了解Promise的都知道他的then函数是链式调用并且顺序执行的。这里先讲一下p.then p.then 与 p.then.then的区别,众所周知p.then会返回一个promise如果then函数中return非Promise会看是不是thenable(理解成有then函数的对象或函数可参考《你不知道的js》(中卷)第二部分第三章)如果thenable中返回resolve()或reject(),then函数将返回一个新的Promise对象状态为resolve或reject的如果非thenable则返回resolve(data)状态的Promise。回到之前的问题,p.then相当于p的Promise的then函数,p.then.then相当于p.then的Promise的then函数,看起来像是说了句废话,但其实好像还真是,开个玩笑,then 如果是同步的那么pp.then 和 pp.then 就会顺序执行而不是异步执行。then函数的顺序链式调用是通过返回新的promise对象控制的,新的promise对象如果状态不发生改变之后的then函数不会执行(类比观察者模式),我理解的then的异步处理是为了不阻塞js进程。
如果你能看到这里那真是太厉害了。Promise对象的错误处理是有一些缺陷的,比如reject()回调函数处理错误,以及catch函数接收错误,看起来是比较完善的错误处理,但是如果没有为then函数设置reject那么错误就被吞并了或者最后一个then中的reject内部报错或catch内部报错那么谁又来捕捉这个错误呢,他返回的是一个promise对象如果为了接收错误不可避免的要用reject和catch但是无法确定他们内部是否报错,总不能无限循环调用catch。在《你不知道的js》中讲到一些Promise库中的处理方法(defer()、done())。
Promise.race方法可以用来做超时处理。
希望道友可以帮我解答一下then的异步处理的作用!!万分感谢