美文网首页
《微信小程序开发之异步转同步》

《微信小程序开发之异步转同步》

作者: 养了个喵 | 来源:发表于2017-12-12 19:47 被阅读0次

问题概述

基于小程序request请求是异步的特性,app.js onLaunch()中的请求与index.js onLoad()中的请求是同时进行的,导致onLoad()中如果有基于onLaunch()返回的数据的请求,会有报错,这样会使onLoad()中request请求的数据“第一次”无法正常获取。

我的小程序中所有的requset请求都需要在header中带着用户唯一的token进行发起,而token是在app.js onLaunch()中的wx.login()返回中获取到的(由code到后台换取),之后通过wx.setStorageSync('token', res.data)存到小程序中。要解决问题,就需要解决request请求异步的问题,而且是在两个js文件之间。

使用Promise()

稍微说一下promise

var promise = new Promise(function(resolve, reject) {
 if (/* 异步操作成功 */){
 resolve(value);
 } else {
 reject(error);
 }
});

promise.then(function(value) {
 // success
}, function(value) {
 // failure
});

Promise 构造函数接受一个函数作为参数,该函数的两个参数分别是 resolve 方法和 reject 方法。

  • 如果异步操作成功,则用 resolve 方法将 Promise 对象的状态,从「未完成」变为「成功」(即从 pending 变为 resolved);
  • 如果异步操作失败,则用 reject 方法将 Promise 对象的状态,从「未完成」变为「失败」(即从 pending 变为 rejected)。

接下来在小程序中引入promise库。到bluebird官网中下载压缩版本的promise库。直接打开bluebird.core.min.js,复制代码。
Bluebird is a fully featured JavaScript promises library with unmatched performance.
小程序内新建一个promise.js文件,将bluebird.core.min.js中的代码复制进去。
app.js中通过require引入:

<!-- app.js -->
const Promise = require('units/promise.js');

这样就可以在小程序内使用promise了,该库大小大概在64kb左右,可以接受。
接下来直接贴代码:

<!-- app.js -->
App({
  onLaunch: function(){
    <!-- 调整代码结构,原本在此进行的wx.login操作放到下面去 -->
    ...
  },
  //登录,获取token
  getToken: function(){
    let _this = this;
    return new Promise(function(resolve, reject){
      wx.checkSession({
        success: function (res) { resolve(res); },
        fail: function (res) {
          wx.login({
            success: res => {
              // 发送 res.code 到后台换取 openId, sessionKey, unionId
              if (res.code) {
                wx.request({
                  url: CONFIG.loginUrl,
                  data: {
                    code: res.code
                  },
                  header: {
                    'shopId': CONFIG.shopId
                  },
                  method: 'POST',
                  success: res => {
                    wx.setStorageSync('token', res.data);  //储存返回的token
                    resolve(res);
                  }
                })
              } else {
                console.log('获取用户登录态失败!' + res.errMsg);
                reject('error');
              }
            }
          })
        }
      })
    })
  }
})

接下来在index.js中处理

const app = getApp();
Page({
  onLoad: function(){
    let token = wx.getStorageSync('token');
    if (token == ''){
      //第一次登录,获取登录状态
      app.getToken().then(function (res) {
        _this.getData();   //此时token必然已经获取到,且getData()在此时才会执行
      })
    }else{
      //有token的情况直接获取数据
      _this.getData();
    }
  },
  //获取数据
  getData: function(){
    wx.request({
      header: {
        'token': wx.getStorageSync('token')
      },
      url: 'https://xxxxx.xxxxx',
      method: 'GET',
      success: res => {
        console.log(res);
      }
    })
  }
})

这时候清除一下开发工具的缓存,再次编译页面,打开调试面板的network,可以看到index.js中的wx.request请求是在wx.login()的success后才开始的,这样就达到了我们的目的,问题解决。

相关文章

网友评论

      本文标题:《微信小程序开发之异步转同步》

      本文链接:https://www.haomeiwen.com/subject/wxanixtx.html