微信小程序全栈开发实践 第三章 微信小程序开发常用的API介绍及使用 -- 3.9 网络接口简介(九)扩展wxp模块的request3方法,实现用户登录的自动融合

零、回顾

在上节课我们主要介绍了观察者模式,
并据此模式实现了一个event模块,
这节课我们基础用户登录的自动整合,
尝试在wxp模块当中扩展出一个request3这样的一个接口。

一、在wxp组件中扩展实现request3接口

3.7中,
当我们单击手动开启登录的时候,
它底部有一个面板滑出。
接下来我们要实现的功能是,
如果是我们用request3去调用接口的时候,
如果发现用户没有登录,也就是没有token,
那么我们把面板自动给它呼出来,让它滑出,
滑出以后,然后用户点击按钮去登录,
登录完成以后,自动地让面板消失,
然后继续我们刚才已经停止的接口请求。
这个大概就是我们想要实现的一个功能

ilb/wxp.js

import {
  promisifyAll
} from 'miniprogram-api-promise';
const wxp = {}
promisifyAll(wx, wxp)

// 3.6 模块化
wxp.request2 = function (args) {
  let token = wx.getStorageSync('token');
  if (token) {
    if (!args.header) args.header = {}
    args.header["Authorization"] = `Bearer ${token}`
  }
  return wxp.request(args).catch(err => console.log("err", err))
}


// 3.9
wxp.request3 = function (args) {
  let token = wx.getStorageSync('token');
  if (!token) {
    // 没有token
    // 返回一个promise对象
    return new Promise((resolve, reject) => {

      // 1.唤起面板
      //1.1 当前页面对象
      //获取当前页面栈
      let pageStack = getCurrentPages();
      // 页面栈最后的一个页面就是我们当前的页面
      if (pageStack && pageStack.length > 0) {

        let currentPage = pageStack[pageStack.length - 1];
        // showLoginPanel:这个变量所有的页面都统一一下
        currentPage.setData({
          showLoginPanel: true
        })



        // 2.面板滑出以后,我们需要监听它成功的事件
        getApp().globalEvent.once("loginSuccess", () => {
          // 成功之后的回调函数
          wxp.request2(args).then(res => {
            resolve(res)
          }, err => {
            console.log("err", err)
            reject(err)
          })
        })

      } else {
        reject("page valid err")
      }


    })

  }

  // 如果有token的话,走request2
  return wxp.request2(args)
}

export default wxp;

pages/api/index.wxml


<view class="page-section">
  <text class="page-section__title">3.9 request3</text>
  <view class="btn-area">
    <button bindtap="testRequest3" type="primary">request3</button>
  </view>
</view>

pages/api/index.js


Page({

  /**
   * 页面的初始数据
   */
  data: {
    showLoginPanel:false
  },
  // 3.9 request3
  async testRequest3(e){
    const app = getApp();

    // 一个需要鉴权的接口
    let res3 = await app.wxp.request2({
      url:'http://localhost:3000/user/home'
    })

    if(res3) console.log("res3",res3);

    // 使用request3
    let res4 = await app.wxp.request3({
      url:'http://localhost:3000/user/home'
    })
    if(res4) console.log("res4",res4);

  },
  ......
})

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、开发中遇到的问题

2.1 wx.request 经 Promise 封装后,如何拿到 RequestTask 实例

实现一:

创建新的类,Request这个类,封装了wx.request接口。
但是这种方法要改变旧的开发模式,会带来新的开发负担。

class Request {
  constructor(parms) {
	  ...
	  this.requestTask = null;
  }
  request(method, url, data) {
	  const vm = this;
	  return new Promise((resolve, reject) => {
		  this.requestTask = wx.request({
		  	...
		  	success(res) {
		  		resolve(res);
		  	},
		  	fail() {
		 	 	reject({...});
		  	}
		  });
	  });
  }
  abort() {
	  if (this.requestTask) {
	  	this.requestTask.abort();
	  }
  }
}
module.exports = Request;
实现二:

是把原生接口返回的RequestTask的实例,
挂载到我们返回的Promise实例上面,
但是这种方式,它会对原生的代码有侵入,
并且在我们代码里面,Promise实例并不是保持不变的,
在wxp.request3中,Promise实例就有所改变。

实现三:

这两种方式虽然可以达到同样的目的,
但却不是我们要采用的最终的一个方法,
那么更好的方式是利用javascript对象被引用传递的这样一个特点,
在这个参数上做手脚。

miniprogram/node_modules/miniprogram-api-promise/src/promise.js:
function _promisify(func) {
	if (typeof func !== 'function') return fn
	return (args = {}) =>{
		return new Promise((resolve, reject)=> {
			let rtnObj = func(
				Object.assign(args, {
					success: resolve,
					fail: reject
				})
			)
			if (args.onReturnObject) args.onReturnObject(rtnObj)
		})
	}
}

我们看一下这个代码,
我们只需要在这个模块当中加一个固定的一个回调属性,
就可以解决这个问题了
if (args.onReturnObject) args.onReturnObject(rtnObj)

在这里插入图片描述
在这里插入图片描述

function _promisify(func) {
  if (typeof func !== 'function') return fn
  return (args = {}) =>
    new Promise((resolve, reject) => {
      // func(
      //   Object.assign(args, {
      //     success: resolve,
      //     fail: reject
      //   })
      // )

      let rtnObj = func(
			Object.assign(args, {
				success: resolve,
				fail: reject
			})
		)
		if (args.onReturnObject) args.onReturnObject(rtnObj)
    })
}

工具–npm构建
在这里插入图片描述

  <button bindtap="requestHomeApiByReq4" type="primary">test abort</button>
 // 3.9 测试 requestTask
  requestHomeApiByReq4(e){
    getApp().wxp.request4({
      url:'http://localhost:3000/user/home',
      onReturnObject(rtn){
        rtn.abort();
        
      }
    }).catch(err=>{
      console.log(err)
    })
  },

重点:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

三、总结

这节课我们主要扩展了wxp模块的request3这个方法,
下节课开始学习tabbar组件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值