微信小程序的 js 代码是 ES6,当前 TypeScript 的 ansyc 可以编译为 ES3/ES5,因此可以用 ansyc 来编写。
使用 ansyc 来编写,最大的好处是代码可读性,相对于ES5的更容易阅读。另外,TypeScript 强制类型检查,使得代码的出错概率减少。
下面是用 ansyc 和 ES5 的代码对比:
// define voice upload function
const uploadVoice = function (next) {
if (!that.data.voice) {
//console.log('no voice to upload');
next(true);
return;
}
const uploadTask = wx.uploadFile({
url: app.globalData.serverOrigin + '/resource?duration=' + that.data.voiceDuration + '&token=' + app.getToken(),
filePath: that.data.voice.tempFilePath,
name: 'resourceFile',
success: function (res) {
//console.log(res);
let resdata = JSON.parse(res.data);
postData.voiceID = resdata.Id;
next(true);
},
fail: function (e) {
console.log('voice upload err:');
console.log(e);
next(false);
}
});
uploadTask.onProgressUpdate(res => {
//console.log('voice file: %d%%', res.progress);
updateProgress(that.data.images.length, res.progress);
});
};
// define after voice uploaded process function
const uploadVoiceNext = function (isSuccess) {
if (isSuccess) {
doPost();
} else {
cancelPost();
}
};
// define after image uploaded process function
const uploadImageNext = function (isSuccess) {
if (isSuccess) {
uploadVoice(uploadVoiceNext);
} else {
cancelPost();
}
};
// define image upload process funciton
const uploadImag = function (i, next) {
if (i == that.data.images.length) {
//console.log('no more image to upload');
next(true);
return;
}
const uploadTask = wx.uploadFile({
url: app.globalData.serverOrigin + '/resource?token=' + app.getToken(),
filePath: that.data.images[i].path,
name: 'resourceFile',
success: function (res) {
//console.log(res);
let resdata = JSON.parse(res.data);
postData.resourceIDs.push(resdata.Id);
if (i < that.data.images.length) {
uploadImag(i + 1, next);
} else {
next(true);
}
},
fail: function (e) {
console.log('image upload err:');
console.log(e);
next(false);
}
});
uploadTask.onProgressUpdate(res => {
//console.log('image file %d: %d%%', i + 1, res.progress);
updateProgress(i, res.progress);
});
};
// begin do upload image one by one and than upload voice by called with uploadimageNext
uploadImag(0, uploadImageNext);
}
使用 ansyc 的 ts 代码:
function uploadFile(url: string, filePath: string, progress?: (progress: number) => never):Promise<number> { return new Promise<number>((resolve, reject) => { const uploadTask = wx.uploadFile({ url: url, filePath: filePath, name: 'resourceFile', success: (res:{data:{Id:number,errMsg?:string},errMsg:string,statusCode:number}) => { if (res.data.errMsg) throw new Error(`upload file[${filePath}] occurs error:${res.errMsg}`) resolve(res.data.Id)}, fail: e => reject(e) }); if (progress){ uploadTask.onProgressUpdate = (res: { progress: number; totalBytesSent: number; totalBytesExpectedToSend: number; }): never => { return progress(res.progress) } } });}async function post2sever(page: IPage) { try { // upload images let fileIDs:number[] = [] for (let img of page.data.images) { let id = await uploadFile(Comm.getRequestUrl('/resource'), img) fileIDs.push(id); } // upload voice let voiceID:number if (page.data.voice){ voiceID = await uploadFile( Comm.getRequestUrl(`/resource?duration=${page.data.voice.duration}`), page.data.voice.path) } // post } catch{ }}
注:使用的微信 API d.ts 来自:https://github.com/Emeryao/typed-we-app
编译成 ES5 时,需要设置 tsconfig.json,添加 lib 内容(由于使用了Object.assign 函数,我加的 lib 是 es6,dom,es2015.promise)
参考:https://www.tslang.cn/docs/release-notes/typescript-2.1.html
低版本异步函数
该特性在TypeScript 2.1之前就已经支持了,但是只能编译为ES6或者ES2015。TypeScript 2.1使其该特性可以在ES3和ES5运行时上使用,这意味着无论您使用什么环境,都可以使用它。
注:首先,我们需要确保我们的运行时提供全局的ECMAScript兼容性
Promise
。这可能需要获取Promise
的polyfill,或者依赖运行时的版本。我们还需要通过设置lib
编译参数,比如"dom","es2015"
或"dom","es2015.promise","es5"
来确保TypeScript知道Promise
可用。
示例
tsconfig.json
{ "compilerOptions": { "lib": ["dom", "es2015.promise", "es5"] }}