我们的小程序的宿主是微信,小程序涉及到很多调用微信功能的场景,如获取用户信息,本地存储,支付功能等;因此,小程序开发框架为我们提供了丰富的微信原生API。小程序将微信原生API分为"事件监听 API"、"同步 API"、"异步API"三类,本文我们主要介绍"同步 API"、"异步API"。
官方约定,以 Sync 结尾的 API 都是同步 API, 如 wx.setStorageSync,wx.getSystemInfoSync 等;但是,此标致并不是绝对的,某些API尽管不是以Sync结尾,但是仍然属于同步API,如wx.createWorker,wx.getBackgroundAudioManager
简单说,就是当你调用同步API的时候,调用结果可以通过当前API的返回值直接获取,如果调用API出错,则直接抛出调用异常的提示语句。同步API会阻塞当前线程。
注:如果API直接返回了我们需要的数据,那么就可以认为这个API是同步模式的
小程序开发框架提供的微信原生 API大多数都是异步的,例如如wx.request,wx.login等
调用异步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仍然是有返回值的,主要是为了实现更加丰富的功能,如wx.request,wx.connectSocket等。
注:如果API的返回值是undefined或者返回的不是我们的目标数据,那么就可以认为此API是异步API
async.wxml
<!--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
// 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
{
"navigationBarTitleText": "微信原生API异步测试",
"backgroundColor": "#FFFFFF"
}
async.wxss
/* pages/async/async.wxss */
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的线程所阻塞
说明:小程序客户端,如果需要实现异步API转同步效果,需要引入"regenerator-runtime"这个包(如下附件)
首先,我们在小程序根目录下创建一个第三方包目录lib,然后将"regenerator-runtime"这个包复制到该目录下
然后实现页面Demo
<!--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>
// 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()
}
})
/* pages/sync/sync.wxss */
{
"navigationBarTitleText": "同步阻塞测试",
"backgroundColor": "#FFFFFF"
}
在阻塞了一段时间之后,最先出现1这个数字,并没有像异步API那样先出现2到6,再出现1
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。