使用Typescript ansyc 编写微信小程序文件上传

微信小程序的 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。这可能需要获取Promisepolyfill,或者依赖运行时的版本。我们还需要通过设置lib编译参数,比如"dom","es2015""dom","es2015.promise","es5"来确保TypeScript知道Promise可用。

示例
tsconfig.json
{
    "compilerOptions": {
        "lib": ["dom", "es2015.promise", "es5"]
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值