前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >微信小程序之同步与异步API

微信小程序之同步与异步API

原创
作者头像
张世强
发布2020-04-27 17:01:03
4.4K0
发布2020-04-27 17:01:03
举报
文章被收录于专栏:zhangzhang

一、理论知识

我们的小程序的宿主是微信,小程序涉及到很多调用微信功能的场景,如获取用户信息,本地存储,支付功能等;因此,小程序开发框架为我们提供了丰富的微信原生API。小程序将微信原生API分为"事件监听 API"、"同步 API"、"异步API"三类,本文我们主要介绍"同步 API"、"异步API"。

1.同步 API

  • 同步API在名称上面有什么特点?此特点是否绝对?

官方约定,以 Sync 结尾的 API 都是同步 API, 如 wx.setStorageSyncwx.getSystemInfoSync 等;但是,此标致并不是绝对的,某些API尽管不是以Sync结尾,但是仍然属于同步API,如wx.createWorkerwx.getBackgroundAudioManager

  • 怎样定义同步API

简单说,就是当你调用同步API的时候,调用结果可以通过当前API的返回值直接获取,如果调用API出错,则直接抛出调用异常的提示语句。同步API会阻塞当前线程。

注:如果API直接返回了我们需要的数据,那么就可以认为这个API是同步模式的

2.异步 API

  • 小程序开发框架提供的微信原生 API以异步模式居多还是同步模式居多?

小程序开发框架提供的微信原生 API大多数都是异步的,例如如wx.requestwx.login

  • 怎么理解异步模式的微信原生 API?

调用异步API时,我们需要传入一个Object回调函数对象作为API的调用参数,例如success、fail、complete(均为函数对象)等,我们将这个Object回调函数对象参数命名为Object-A,由于异步微信原生 API的调用结果不是通过 API直接返回的,所以我们需要调用Object-A这个回调函数并入参另外一个Object作为Object-A的调用参数,如errMsg、errCode等。我们将Object-A的调用参数命名为Object-B,这个对象有一些属性字段,如data获取异步API的执行结果,code获取异步API的执行状态码。参考图示:

异步API不会阻塞当前线程

  • 异步API是否会有返回值?

多数异步API是没有返回值的,需要通过回调函数获取执行结果,但部分异步API仍然是有返回值的,主要是为了实现更加丰富的功能,如wx.requestwx.connectSocket等。

注:如果API的返回值是undefined或者返回的不是我们的目标数据,那么就可以认为此API是异步API

二、演示Demo

1.异步API非阻塞线程

小程序端

async.wxml

代码语言:javascript
复制
<!--pages/async/async.wxml-->
<view>{{ oneone }}</view>
<view>{{ one }}</view>
<view>{{ two }}</view>
<view>{{ three }}</view>
<view>{{ four }}</view>
<view>{{ five }}</view>
<view>{{ six }}</view>
<view>{{ result }}</view>
<button bindtap="clickMe">点击我</button>

async.js

代码语言:javascript
复制
// pages/sync/sync.js
Page({
  /**
   * 页面的初始数据
   */
  clickMe: function() {
    var that=this;
    let res=wx.request({
      url: 'https://tencentcloud.cdhwdl.com:3000', //仅为示例,并非真实的接口地址
      method:'post',
      timeout:30000,
      data: {
        x: ""
      },
      header: {
        'content-type': 'application/json' // 默认值
      },
      success (res) {
        that.setData({
          one: res.data.res
        })
        console.log(res.data)
      }
    })
    that.setData({
      result:"request函数返回值:         "+res.data,
      two: 2,
    })
    that.setData({
      three: 3,
    })
    that.setData({
      four: 4,
    })
    that.setData({
      five: 5,
    })
    that.setData({
      six: 6,
    })

  }
})

async.json

代码语言:javascript
复制
{
  "navigationBarTitleText": "微信原生API异步测试",
  "backgroundColor": "#FFFFFF"
}

async.wxss

代码语言:javascript
复制
/* pages/async/async.wxss */

服务端

代码语言:javascript
复制
const https = require('https');
const fs = require('fs');
const path = require('path');

const privateKey  = fs.readFileSync(path.join(__dirname, './certificate/server.key'), 'utf8');
const certificate = fs.readFileSync(path.join(__dirname, './certificate/server.crt'), 'utf8');
const credentials = {key: privateKey, cert: certificate};
function sleep(milliSeconds) {
    var startTime = new Date().getTime();
    while (new Date().getTime() < startTime + milliSeconds);
}
const httpsServer = https.createServer(credentials,function(req, res){
    let body = [];
    req.on('data', (chunk) => {
        body.push(chunk);
    }).on('end', () => {
        sleep(20000);
        res.end(JSON.stringify({res:1}));
    });
});

const SSLPORT = 3000;
httpsServer.listen(SSLPORT, '0.0.0.0', () => {});

演示效果

添加描述

20秒后

我们可以看到1这个数字是后端在20秒时才返回的,而2到6这5个数字在脚本执行完成之后就渲染到了页面中,并没有被获取1的线程所阻塞

2.同步API阻塞线程

说明:小程序客户端,如果需要实现异步API转同步效果,需要引入"regenerator-runtime"这个包(如下附件)

首先,我们在小程序根目录下创建一个第三方包目录lib,然后将"regenerator-runtime"这个包复制到该目录下

然后实现页面Demo

  • sync.xml
代码语言:html
复制
<!--pages/sync/sync.wxml-->
<view>{{ one }}</view>
<view>{{ two }}</view>
<view>{{ three }}</view>
<view>{{ four }}</view>
<view>{{ five }}</view>
<view>{{ six }}</view>
<button bindtap="clickMe">点击我</button>
  • sync.js
代码语言:javascript
复制
// pages/sync/sync.js
//获取应用实例
require('../../lib/regenerator-runtime/runtime')
const app = getApp()

Page({
  // 初始化
  async init () {
    await this.getData()  // 请求数据
    await this.postData()
  },
  postData: function(){
    return new Promise((resolve, reject) => {
      wx.request({
        url: 'https://tencentcloud.cdhwdl.com:3000',
        method: 'POST',
        data: {
          x:""
        },
        success (res) {
          console.log(res)
          resolve(res.data)
        },
        fail (err) {
          console.log(err)
          reject(err)
        }
      })
    })
  },
  // 获取列表
  getData: function() {
    return new Promise((resolve, reject) => {
      this.postData().then((res) => {
        this.setData({
          one: res.res,
        })
        this.setData({
          two: 2,
        })
        this.setData({
          three: 3,
        })
        this.setData({
          four: 4,
        })
        this.setData({
          five: 5,
        })
        this.setData({
          six: 6,
        })
        console.log(res)
        resolve()
      })
        .catch((err) => {
          console.error(err)
          reject(err)
        })
    })
  },  
  clickMe: function(){
    this.getData()
  }
})
  • sync.wxss
代码语言:javascript
复制
/* pages/sync/sync.wxss */
  • sync.json
代码语言:javascript
复制
{
  "navigationBarTitleText": "同步阻塞测试",
  "backgroundColor": "#FFFFFF"
}

演示效果

在阻塞了一段时间之后,最先出现1这个数字,并没有像异步API那样先出现2到6,再出现1

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、理论知识
    • 1.同步 API
      • 2.异步 API
      • 二、演示Demo
        • 1.异步API非阻塞线程
          • 小程序端
          • 服务端
        • 演示效果
          • 2.同步API阻塞线程
            • 演示效果
            相关产品与服务
            云开发 CloudBase
            云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档