云裂变营销网

标题: 小程序异步和Promise [打印本页]

作者: 匿名    时间: 2023-3-10 11:48
标题: 小程序异步和Promise
前序

异步算法经常出现在网站的应用中。比如前端已经获取到用户的登陆名称,要向网站关联的服务器后端发送指令查询用户的数据并返回,然后跳转到用户的详情页。如果不作异步要求,后端的数据还没有返回,网页就已经跳转到详情页,那详情页除了用户名,其它数据就无法正常显示了。所以要用到异步操作。如果指定向网络上查询数据的运行是异步的,那跳转的工作就必须等返回数据才会执行,就能达到想要的效果。
再比如两行代码,向硬盘上写一个文件,打开这个文件。运行时,一般情况都是写文件的命令发出了,接着就马上执行打开文件的命令。问题是写文件还没有完成,结果就是文件被占用无法打开文件的错误。一个解决办法就是不停的发出打开文件的指令并catch,等待能打开文件为止。不停的发出打开文件的指令就相当于把存文件这个命令改为异步的了。
小程序云开发也是相同的情况。由于云开发,是调用云上的方法或资源,与网站浏览器端调用网站后台的原理相似。网上服务器端距离电脑端路程比较远,访问返回可能需要花销的时间比较长,就有必要区分同步和异步的需要。如果需要云上信息的返回,依据返回的数据进行下一步的操作,就需要异步的处理方法。
异步的简单理解

同步就是一段代码是同步进行(虽然是按顺序进行,但发出命令就行了)。发出指令的时间足够短,这一系列指令代码就是看作同步的。
异步就是其中的某条或多条代码,定义为异步,其后面的代码都必须等这些异步的代码有返回通知,才能按序执行。
就好比,一位领导召集所有的下属到广场上,给所有人安排任务。领导点名到谁,谁就立即出发执行任务。点名这个行为几乎不需要什么时间,那出去执行任务就可以看成是同步去执行任务。如果是A和A后面的人的任务之间有相关性(可能是做同样的工程),比如A和A后面的人都只会做自己熟悉的工作,而这些工作必须A完成后,后面的人才能去执行自己的任务。那只能这样安排,等A执行完任务后,后面的人在A的执行成果的基础上再去执行各自的任务。这样A的执行任务就是异步的。A的异步影响到后面人的任务执行时间。
小程序的异步操作

同步调用云函数

先看一个例子,比如小程序首页js文档的代码如下:
  1. Page({
  2.   onLoad(options) {
  3.     wx.cloud.callFunction({
  4.       name: 'quickstartFunctions',
  5.       data: {
  6.         type: 'getOpenId'
  7.       }
  8.     }).then((resp) => {
  9.         console.log(resp.result.openid)
  10.       }).catch((e) => {
  11.         console.log(e)
  12.       })
  13.   }
  14. })
复制代码
这是一个小程序网页端向小程序后台(小程序云)查询返回openid的例子。onLoad是网页加载时要执行的代码事件。wx.cloud.callFunction就是网页加载时要执行的代码。then、catch这种格式的官方称之为Promise风格。也可以写成非Promise风格的。如下:
  1.      await wx.cloud.callFunction({
  2.        name: 'quickstartFunctions',
  3.        data: {
  4.          type: 'getOpenId'
  5.        },
  6.        success: function (res) {
  7.          console.log(res)
  8.        },
  9.        fail: function (res) {
  10.          console.log("错误")
  11.        }
  12.      })
复制代码
console.log:就是开发工具控制台打印出运行结果。
then:就是wx.cloud.callFunction运行结束后成功时(success)要执行的代码。
参数resp:返回的数据,是JOSN格式。所以要得到openid,还要知道resp的对象结构,这里可以用res.result.openid来获取。
catch:云函数执行失败事件。
一般情况下,都能返回正确的openid。如果写成以下代码:
  1. var openid='openid';
  2. Page({
  3.   onLoad(options) {
  4.    wx.cloud.callFunction({
  5.       name: 'quickstartFunctions',
  6.       data: {
  7.         type: 'getOpenId'
  8.       }
  9.     }).then((resp) => {
  10.        openid = resp.result.openid;
  11.        console.log(openid);
  12.     }).catch((e) => {
  13.        openid = '云函数执行错误';
  14.        console.log('云函数执行错误');
  15.     })
  16.     console.log(openid);
  17.   }
  18. })
复制代码
就无法同步得到返回的openid。如下图:

小程序异步和Promise-1.jpg
说明代码还未等云函数then成功返回openid就转到了最后那行,把openid打印出来。然后才是then获得正确的openid后再打印出来。就因为then这里的运行不是异步的。因此程序不等待then的运行,就执行了获取openid的操作。如果这时用这个openid存到数据库,那就会有错。正确的办法是在then函数里面执行保存openid的操作。
把page代码改为以下:
  1. Page({
  2.   onLoad(options) {
  3.     var data = '显示结果';
  4.     data = wx.cloud.callFunction({
  5.       name: 'quickstartFunctions',
  6.       data: {
  7.         type: 'getOpenId'
  8.       }
  9.     })
  10.     console.log(data);
  11.   }
  12. })
复制代码
执行结果如下:

小程序异步和Promise-2.jpg
Promise是异步的

可以打开quickstartFunctions和getOpenId的js文档看

小程序异步和Promise-3.jpg

小程序异步和Promise-4.jpg

小程序异步和Promise-5.jpg
说明quickstartFunctions和getOpenId都是异步的。但小程序端的wx.cloud.callFunction执行却没有指定为异步。
结果是个Promise对象,展开这个Promise,里面还是有openid的。如下图:

小程序异步和Promise-6.jpg
但很难拿到openid这个数据。没有像success后那样容易拿到。
小程序云的函数,基本都是用Promise的方法。关于Promise对象和Promise的异步执行原理,可自行查找资料。
但没有成功事件的返回参数resp,就不能像resp.result.openid那样轻易的得到openid了。
异步调用云函数

改为以下代码:
  1. //力先代码示例
  2. var openid='openid'
  3. Page({
  4.   onLoad(options) {
  5.     this.GetUserOpenId();
  6.   },
  7.   async GetUserOpenId() {
  8.     console.log(1);
  9.     await this.GetUserOpenIdModule();
  10.     console.log(3);
  11.     console.log(openid);
  12.   },
  13.   async  GetUserOpenIdModule() {
  14.     await wx.cloud.callFunction({
  15.       name: 'quickstartFunctions',
  16.       data: {
  17.           type: 'getOpenId'
  18.       }   
  19.     })
  20.       .then((resp) => {  
  21.         console.log(2);
  22.         openid=resp.result.openid;
  23.       }).catch((e) => {
  24.       });
  25.   }
  26. })
复制代码
调试就可以得到预期的效果了。如下图:

小程序异步和Promise-7.jpg
var openid:定义了页面全局变量,页面里面的代码都可以直接引用。
GetUserOpenId函数:在Page里面的函数,页面内的其它函数访问都必须加this去访问。
await this.GetUserOpenIdModule():异步指令,等待GetUserOpenIdModule函数里面的代码都执行完毕才能同步到下一条代码。由于有了await关键词,所在的函数必须加上async(异步)关键词。
await wx.cloud.callFunction:等待调用云函数的操作执行完毕。
这样做的好处可能是不需要必须在then或success事件里面写处理返回数据的代码,简明代码的层次。
结语

要获取小程序云函数的处理结果,就得相应的使用异步的方法。本文稍微展开研究了小程序云函数的异步方法。




欢迎光临 云裂变营销网 (https://www.yunliebian.com/yingxiao/) Powered by Discuz! X3.4