第三篇:小程序之网络请求

对于小程序而言,网络请求封装的要比Android强大多了,这一点值得赞扬。官方示例:

wx.request({
  url: 'test.php', //仅为示例,并非真实的接口地址
  data: {
     x: '' ,
     y: ''
  },
  header: {
    'content-type': 'application/json' // 默认值
  },
  success: function(res) {
    console.log(res.data)
  }
})

but...but...这调用起来貌似很简单,但是,似乎有点不对劲?哪儿不对劲呢——每次调用的代码太多了。而且,对于网络请求的日志文件不好管理。这离我们最理想的方式还是有点差距的。
那么,我们最理想的方式是希望是怎么样的呢?

1、代码简洁,一行代码去搞定。
2、对于常用的字段统一封装管理。如 token、版本号version等
3、自定义异常处理。如未登录时,不用每写一个接口都去判断是否登录、注册等

 api.request1(data, function (result) { //数据请求成功,
  },
   function(error){//失败
 })

那么,基于上面的问题。我来一步步进行剖析。

一、网络请求的场景分析

1、支持token传入的网络请求。

这种情况比较少见的。我现在的项目中就遇到了。大概意思是管理员可以操作旗下的其他的虚拟用户。管理员登录后生成一个token,每生成一个成员时,会生成一个虚拟的virtualToekn,以后每次管理员操作这个成员时,都需要用这个virtualToken,但是管理员获取自己的信息时,还是需要用自己的token。这个时候就要支持自定义的token传入了。

2、网络请求的劫持。

这种场景主要有两种情况:

1、如果网络失败
2、没有token时,这种场景主要出现在登录后置中。如商城类app查看购物车等

解决方法:直接返回失败,在发起网络请求前结束本次网络请求操作,减少预知的错误网络访问

3、支持自定义loading窗的弹出和隐藏控制

1、loading窗的弹出:这种场景比较多,如下拉刷新列表时,是不需要loading窗出现的。但是获取用户信息是需要loading出现的
2、loading窗的隐藏:这种场景是如果调用一个接口成功后,然后要连续调用第二个接口。这样在第一次接口成功后,不应该让loading窗消失,而是最后一次接口结束后才隐藏。

4、对网络不同的错误,进行处理

二、代码分析

/**
 * 自定义token  请求
 * 
 * isShowLoading :true  弹出loading窗
 * isEndLoading: true  最后需要隐藏loading窗。若是false,则不隐藏
 * token: 可以自定义token。用户虚拟账号使用车辆
 */
export function requestApi(requestData, isShowLoading = true,isEndLoading = true, token = null,onSuccess, onFail) {
  let app = getApp().globalData;
  // 1、检查是否已经登录,在未登录的时候,可以提前缓存一个临时token欺骗本次检查。等登录完成后,再更新token值
  if (!util.hasLogin()) {
    return;
  }
  // 2、检查网络状态
  if (!util.checkNetworkConnected()) { //没有网络
    onFail("网络请求失败,稍后再试")
    return;
  }
  if (!requestData) {
    onFail("数据异常,请稍后再试")
    return;
  }
  let cacheToken =  util.takeToken()
  let newToken = token == null ? cacheToken : token
  console.log("newToken===========>", newToken)
  requestData.token = newToken
  requestData.version = app.version
  console.log("==================================================开始请求网络数据start========================================")
  console.log(requestData)
  console.log("==================================================开始请求网络数据end===========================================")
  var baseUrl = app.debug ? app.debugUrl : app.releaseUrl    
  console.log("===baseUrl===>" + baseUrl)
  if (isShowLoading){
    util.showLoading("加载中")
  }
  const requestTask = wx.request({
    url: baseUrl,
    data: requestData,
    header: {
      'content-type': 'application/json'
    },
    method: 'POST',
    dataType: 'json',
    success: function(res) {
      console.log("==================================================返回请求结果start========================================")
      console.log(res.data)
      console.log("==================================================返回请求结果end===========================================")
      if (res.data.code == 0) { //成功
        // console.log("onSuccess===========>", onSuccess);
        onSuccess(res.data)
      } else if (res.data.code == 1021) { //未缴纳押金
        wx.navigateTo({
          url: '/pages/recharge/recharge',
        })
        return false;
      } else if (res.data.code == 1006) { //余额不足
        wx.navigateTo({
          url: '/pages/deposited/deposited',
        })
        return false;
      } else if (res.data.code == 1019) { //未实名
        wx.navigateTo({
          url: '/pages/certify/certify',
        })
        return false;
      } else if (res.data.code == 1001) { //token过期
        wx.reLaunch({
          url: '/pages/login/login'
        });
        return false;
      } else { //失败
        let error = res.data == null || typeof (res.data) == "undefined" ? "网络请求失败,请稍后再试" : res.data.desc
        onFail(error)
        console.log("error===========>", error);
      }
    },
    fail: function(res) {
      console.log("onFail===========>", res);
      onFail("网络请求失败,稍后再试")
    },
    complete: function(res) {
      console.log("complete===========>", isEndLoading);
      if (isEndLoading){
        wx.hideLoading()
      }
    }
  })
};

三、网络环境统一切换。

在app.json中统一配置

  // 全局的数据,可以提供给所有的page页面使用
  globalData: {
    token: "",
    version: "version版本号",
    releaseUrl: "正式版url",
    debugUrl: "测试版url",
    debug: true   //true  debug环境,false正式环境
  },

这样,以后切换网络环境只需要修改debug值即可。

四、二次封装

/**
 * 自定义loading  框请求
 * 
 * isShowLoading :true  弹出loading窗
 * isEndLoading: true  最后需要隐藏loading窗。若是false,则不隐藏
 */
export function request(requestData, isShowLoading = true, isEndLoading = true, onSuccess, onFail){
  this.requestApi(requestData, isShowLoading, isEndLoading, null, function (result) {
    onSuccess(result)
  }, function (error) {
    onFail(error)
  })
}

/**
 *  带有loading 框的 不能自定义的请求
 * 
 */
export function request1(requestData, onSuccess, onFail) {
  // console.log("onSuccess========request1===>", success, fail);
  requestApi(requestData, true, true, null, function (result) {
    onSuccess(result)
  }, function (error) {
    onFail(error)
  })
}

/**
 * 自定义token  请求
 * 
 * isShowLoading :true  弹出loading窗
 * isEndLoading: true  最后需要隐藏loading窗。若是false,则不隐藏
 * token: 可以自定义token。用户虚拟账号使用车辆
 */
export function request2(requestData, isShowLoading = true, isEndLoading = true, token = null, onSuccess, onFail) {
  requestApi(requestData, isShowLoading, isEndLoading, token, function (result) {
    onSuccess(result)
  }, function (error) {
    onFail(error)
  })
}

/**
 * 自定义loading  框请求
 * 
 * isShowLoading :true  弹出loading窗
 * isEndLoading: true  最后需要隐藏loading窗。若是false,则不隐藏
 */
export function request3(requestData, isShowLoading = true, isEndLoading = true, token, onSuccess, onFail) {
  requestApi(requestData, isShowLoading, isEndLoading, token, function (result) {
    onSuccess(result)
  }, function (error) {
    onFail(error)
  })
}

end

最后,控制台查看日志的示意图为:


网络请求.jpg

详细代码去查看github

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,558评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,002评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,024评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,144评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,255评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,295评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,068评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,478评论 1 305
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,789评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,965评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,649评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,267评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,982评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,800评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,847评论 2 351

推荐阅读更多精彩内容