正确操作:
1.不勾选es6转es5的选项
2.勾选“增强编译”的选项
3.开发工具版本号:微信开发工具版本>=1.02.1904282
4.用promise对函数进行封装
总结1:关于启用async await语法
1.async+await是 ES7 的一个特性。在最新的ES7(ES2017)中提出的前端异步特性:async、await。
2.微信开发工具目前仅具有编译ES6 的能力。
3.为了支持ES7 的async+await,微信开发工具通过新增“增强编译”的选项来实现对ES7 的async+await的支持。
4.所以只要保证勾选“增强编译”的选项,即可用async+await来开发小程序。
5.微信开发工具1.02.1904282 以及之后版本,才有增强编译的选项。所以必须下载至少1.02.1904282 之后的版本。
增强编译
在 1.02.1904282 以及之后版本的开发工具中,增加了增强编译的选项来增强ES6转ES5的能力,启用后会使用新的编译逻辑以及提供额外的选项供开发者使用。
启用增强编译后的支持对Async/Await 的编译,未启用则不支持对对Async/Await 的编译
官方文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/codecompile.html
test
下面的代码,只要勾选了“增强编译”的选项,无论ES6转ES5勾选或者不勾选,运行都是正常的。
//app.js
async fun() {
setTimeout(function () {
}, 3000)
console.log("test1")
},
async fun2() {
console.log("test2")
},
onLaunch: async function () { //当小程序初始化完成时,会触发onLaunch(全局只触发一次)
await this.fun()
await this.fun2()
console.log("fun()已执行完成!")
output:
test1
app.js? [sm]:42 test2
app.js? [sm]:50 fun()已执行完成!
总结2:关于不勾选es6转es5的选项
使用案例:https://github.com/pampa0629/EntryOutdoor
在上面的基础上,微信小程序客户端如果使用了用promise进行封装的函数, async + await,会报这个错误
原因:async+await是 ES7 的一个特性。在最新的ES7(ES2017)中提出的前端异步特性:async、await。如果微信小程序IDE里开启了ES6转ES5,则会报这个错误。
ReferenceError: regeneratorRuntime is not defined
解决方案:
第一种方法:微信小程序IDE里,详情->本地设置 里,不勾选es6转es5,开启,【增强编译】
开发工具勾选ES6转ES5的情况下使用ES7的async,await
解决方案
引入 regenerator runtime.js
demo:https://github.com/TencentCloudBase/tcb-demo-basic/tree/master/client/libs
以操作适用开发工具勾选ES6转ES5的情况
step 1:先导入 regenerator-runtime
regenerator,使用 regenerator,这是 facebook 下的一个工具,用于编译 ES6 的 generator 函数。
在需要使用async/await特性的代码文件中,引入regenerator库
js
// miniprogram/pages/adminEmployee/login/index.js
//step 1: use runtime.js
const regeneratorRuntime = require('../../../lib/regenerator-runtime/runtime')
or
import regeneratorRuntime from '../../libs/regenerator-runtime'
download url for regenerator-runtime.js:
https://github.com/facebook/regenerator/tree/master/packages/regenerator-runtime
总结3:关于对函数用promise进行封装以便使用async await语法
在这块里头,有三个分支可以选择,开发者可以选择其中的一种:
分支1:对函数用promise进行封装以便使用-直接使用promise进行封装
1.对云函数的封装及其调用方法
page.js
//从数据库中获取管理后台密码 同步方式
async getAdminPassword() {
const db = wx.cloud.database();
await db.collection(configCollection.Setting).where({
Name: "AdminPassword"
}).get({
success: res => {
this.setData({
AdminPassword: res.data[0], //返回的是一个数组,取第一个,
})
},
fail: err => {
console.log(err)
}
})
},
call
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.init();
},
async init() {
try {
await this.getAdminPassword();
console.log('run await getAdminPassword() ok')
} catch (error) {
console.log('run await getAdminPassword() error')
}
},
2.1.对 wx.request函数的封装及其调用方法
函数加上async关键字,在原wx.request函数基础上用promise将其包裹起来,然后添上resolve(res); 和reject(err);即完成了封装
//获取1个员工对象
getEmployeesByOpenIdPromiseFromApi2: async function (openid) {
return new Promise((resolve, reject) => {
wx.request({
url: 'https://api.demo.com/api/Employee/EmployeesByOpenid/' + openid, //仅为示例,并非真实的接口地址
data: {
},
header: {
'content-type': 'application/json' // 默认值
},
success(res) {
console.log(res.data)
if (res.data.length > 0 && res.statusCode == 200) {
getApp().globalData.Employee = res.data[0];
}
else {
console.log("app.js获取的员工信息失败:res.statusCode==" + res.statusCode)
}
resolve(res);
},
fail: function (res) {
console.log("失败" + res);
reject(err);
}
})
});
},
call
page.js的原有函数,我们不动它,只将onload加上一个async关键字
old
onLoad: function (options)
new
onLoad: async function (options)
然后用await关键字进行调用
onLoad: async function (options) {
//首先查找用户是否存在
var openid = getApp().globalData.openid;
//用async/await 函数调用
try {
let res = await app.getEmployeesByOpenIdPromiseFromApi2(openid);
console.log('pages/adminEmployee/index/index->Onload() Info: call app.getEmployeesByOpenIdPromiseFromApi2(openid) ok res=' ,res)
} catch (error) {
console.log('pages/adminEmployee/index/index->Onload() Info:app.getEmployeesByOpenIdPromiseFromApi2(openid) err,eror=' ,error)
}
},
if (res.data.length > 0 && res.statusCode == 200) {
getApp().globalData.Employee = res.data[0];
// this.app.globalData.Employee = res.data[0];
console.log("app.js获取的员工信息OK:getApp().globalData.Employee=" , getApp().globalData.Employee)
}
else {
console.log("app.js获取的员工信息失败:res.statusCode==" + res.statusCode)
}
分支2:对函数用promise进行封装以便使用-使用wxPromisify.js库进行封装
案例:https://github.com/bandazhenxin/htMeow
utils/webServer/asyn/wxAsyn.js
/**
* 同步化封装原厂开放接口
*/
const wxPromisify = require('wxPromisify.js');
//api list
const getLocation = wxPromisify(wx.getLocation); //获取经纬度
const showModal = wxPromisify(wx.showModal); //弹窗
const getSetting = wxPromisify(wx.getSetting); //判断权限
const getUserInfo = wxPromisify(wx.getUserInfo); //获取用户信息
const login = wxPromisify(wx.login); //登录
const openSetting = wxPromisify(wx.openSetting); //弹出授权
module.exports = {
getLocation: getLocation,
showModal: showModal,
getSetting: getSetting,
getUserInfo: getUserInfo,
login: login,
openSetting: openSetting
}
分支3:TypeScript 2.1
1.小程序客户端中支持使用async/await有四种模式
目前,小程序中支持使用async/await有四种模式:
1.1纯原生es7的async/await模式
1.2勾选es6转es5,勾选增强编译;一般是因为调用了第三方的es5插件,通过增强编译支持async/await。
1.3勾选es6转es5,不勾选增强编译;手工引入runtime.js支持async/await
1.4 微信小程序]使用TypeScript2.1 async/await
2.小程序客户端中支持使用async/await四种模式详细情况说明
1、不勾选es6转es5,不勾选增强编译;该模式是纯原生es7的async/await,需要基础库高版本。
从线上运行的结果来看,不支持原生async/await的手机型号已经没有了(或者少到我们发现不了了),所以已经没理由再用es5下的async/await了,放弃它。
小程序(包括工具)已经原生支持async/await了,直接用就行了。(别勾es6转es5)
案例项目:
https://github.com/pampa0629/EntryOutdoor/blob/master/project.config.json
{
"description": "项目配置文件",
"packOptions": {
"ignore": []
},
"setting": {
"urlCheck": true,
"es6": false,
"enhance": true,
"postcss": true,
...
},
"libVersion": "2.8.3",
2、勾选es6转es5,勾选增强编译;一般是因为调用了第三方的es5插件,通过增强编译支持async/await。
3、勾选es6转es5,不勾选增强编译;手工引入runtime.js支持async/await。
线上版本报错:
在使用async await时回报
VM4677:1 thirdScriptError
sdk uncaught third Error
Function(...) is not a function
TypeError: Function(...) is not a function
Page is not constructed because it is not found.
使用async await出现regeneratorRuntime is not defined错误
原因是:
runtime.js 更新了,改东西!!!
到此下载可以使用的版本
https://github.com/sxshuang/19613regenerator-runtime
https://blog.csdn.net/sxs7970/article/details/91880231
TypeScript2.1 微信小程序]使用 async/await
https://www.cnblogs.com/emeryao/p/6208429.html
TypeScript 支持
如果项目需要使用 TypeScript 语言开发,开发者工具在创建项目选择快速启动模板时,提供了使用 TypeScript 语言的 QuickStart 项目,可以选择创建此项目并进行后续开发。
要构建并使用 TypeScript 项目,可能需要安装 npm。通过配置编译前的预置命令,可以实现在编译前运行 tsc 以将其编译到 js 文件。
如需配置 TypeScript 编译选项,请参考 tsconfig.json 的配置。
注:小程序仅支持运行 JS 文件,因此所有的 TS 文件都默认不会被打包上传。
Git 状态展示
come from office doc:https://developers.weixin.qq.com/miniprogram/dev/devtools/edit.html#TypeScript-支持
据最近更新情况,原生的函数已经大部分同时原生支持同步化了,不需要本方案转化了,直接加上await即可;比如wx.chooseImage、wx.showModal
ES6 转 ES5
在 0.10.101000 以及之后版本的开发工具中,会默认使用 babel 将开发者 ES6 语法代码转换为三端都能很好支持的 ES5 的代码,帮助开发者解决环境不同所带来的开发问题。
需要注意的是:
为了提高代码质量,在开启 ES6 转换功能的情况下,默认启用 javasctipt 严格模式,请参考 "use strict"
增强编译
在 1.02.1904282 以及之后版本的开发工具中,增加了增强编译的选项来增强ES6转ES5的能力,启用后会使用新的编译逻辑以及提供额外的选项供开发者使用。
https://developers.weixin.qq.com/miniprogram/dev/devtools/codecompile.html
https://developers.weixin.qq.com/community/develop/article/doc/0008ee7efe4cf0a25799a071c5b013
我们做小程序开发时,要使得自己代码变得整洁,异步操作时避免回调地狱.应该使用
es6的promise.
es7的async,await .
云函数:promise在小程序和云开发的云函数里都可以使用. async和await只能在云开发的云函数里使用.
小程序客户端使用async,await过程
step 1:勾上增强编译
step 2:引入 regenerator
https://codeload.github.com/facebook/regenerator/zip/master
https://github.com/facebook/regenerator/tree/master/packages
├─lib
│ ├─regenerator-runtime runtime.js
│ └─wxParse
├─pages
│ ├─auth
在根目录下创建 lib 文件夹,并将 https://github.com/facebook/regenerator/tree/master/packages 里面的 regenerator-runtime 文件夹放进去。
然后在使用async-awiat的页面中引入:
step 3:
js
const regeneratorRuntime = require('../../../lib/regenerator-runtime/runtime')
step 4:改造wx.abcd()方法
使用promise()对现有函数进行封装。
函数声明: async function foo() {}
函数表达式: const foo = async function() {}
对象的方式: let obj = { async foo() {} }
箭头函数: const foo = async () => {}
https://developers.weixin.qq.com/community/develop/doc/00064622cc42802e908875c4456800