先说一下什么是异步,我举一个通俗易懂的例子。
你现在有两个任务:
- 向Java老师要一份复习资料
- 买一瓶矿泉水
如果你是同步执行,那么你的执行过程就是,先去向老师要一份复习资料,等老师把复习资料给到了你的手里,然后你才去买那瓶矿泉水。
但是如果你是异步执行,那么你的执行过程就是,跑到老师面前,跟老师说,老师我要一份复习资料,然后你就立刻去买矿泉水了,在你买矿泉水的时候,那份复习资料,你可能拿到了,可能没拿到,取决于实际的情况。
大家应该能明白我表达的意思。
然后我们讨论一个问题,在程序执行中,到底是同步好还是异步好。答案肯定是不确定。要根据实际的业务场景才能分析出是同步好还是异步好,它们没有一个绝对的利害关系。
然后我们说一下微信小程序中的异步问题,微信小程序中大部分的API请求都是异步的,可能一些初学者在进行程序编写的时候,会发生一些很诡异的事情。就是,我看这段程序看了一遍又一遍,没发现任何错误,但是程序执行之后,答案就是不符合我的预期。很有可能你就是中了异步的坑了。因为你没有了解过异步执行,一直在用同步执行的思维解决问题。
我举一个代码的例子:
这是一个最简单的查询云函数的代码。
看一下云函数的内容:
只是给return一个字段为status值为success的数据。
然后看一下客户端JS的代码:
selectCloudFunction(){
var status = null;
wx.cloud.callFunction({
name:'test',
success(res){
console.log(res);
status = res.result.status;
}
})
console.log("云函数执行结果是",status);
},
进行一个最简单的查询,对于初学者来说,经常这样写代码。在他们的理解里,程序的执行顺序是由上至下。我调用云函数之后,在success回调里给status赋了云函数的回调值。执行完云函数之后,我在下面输出一下我刚才赋值的变量,看一下赋值有没有成功。
思路似乎没有问题,但是这是同步的思路,很遗憾,云函数的调用是异步执行的。
我们看一下这样写的控制台输出。
status的值依然是null,而且我们可以很明显的注意到这两个console.log的输出时间似乎不符合我们的预期,下面的输出竟然优于上面的输出先执行。
天呐,到现在很多小朋友都会崩溃,这是什么人间疾苦。
不要慌张,下面我们来解决一下这个问题。
如果你没有学过ES6、ES7的话,我建议你使用回调嵌套的解决办法。
代码如下:
selectCloudFunction(){
var status = null;
wx.cloud.callFunction({
name:'test',
success(res){
console.log(res);
status = res.result.status;
console.log("云函数执行结果是",status);
}
})
},
因为代码过于简单,可能看不出太大的区别,但是我们看控制台的输出,现在的输出结果已经符合我们的预期了。
这是对于初学者来说,最无脑的解决方法。但是当代码量增多的时候,就会产生回调地狱的情况,层层嵌套,到时候代码维护起来十分的困难。
在ES6,有了Promise来解决异步问题。
先看代码:
selectCloudFunction(){
var status = null;
var promise = new Promise((resolve,reject) => {
wx.cloud.callFunction({
name:'test',
success(res){
console.log(res);
status = res.result.status;
resolve();
}
})
});
promise.then(()=>{
console.log("云函数执行结果是",status);
})
},
这是ES6的语法,它解决了我们的问题。可能现在看起来,不如回调嵌套方便,这是因为我演示的代码很简单,很基础。当你的代码量很大的时候,promise绝对要优于回调嵌套的。而且可以对promise进行一些封装,更好的解决实际需求。
其实promise并不是最优雅的解决异步的方法。
在ES7中有了 async await 可以更加优雅的解决异步问题,并且是目前这个问题领域中的最优解。
但是现在的微信小程序的客户端目前是完全支持Promise的,并不直接支持async await,如果想用async await,还需要npm 依赖,分离js文件 ,require调用。对初学者并不友好。有兴趣的同学可以了解一下。
点赞、关注、收藏都是对作者莫大的鼓励,感谢!
个人QQ:505417246
关注下面微信公众号,可以领取微信小程序、Vue、TypeScript、Web前端基础、uniapp、Nodejs、Python、Java等学习资料