当前位置: 首页 > news >正文

运动分类的网站设计论文考研资料找微信hyhyk1推广可以

运动分类的网站设计论文,考研资料找微信hyhyk1推广可以,wordpress迅雷下载,帝国cms 网站地址设置网络请求封装 网络请求模块难度较大#xff0c;如果学习起来感觉吃力#xff0c;可以直接学习 [请求封装-使用 npm 包发送请求] 以后的模块 01. 为什么要封装 wx.request 小程序大多数 API 都是异步 API#xff0c;如 wx.request()#xff0c;wx.login() 等。这类 API 接口…网络请求封装 网络请求模块难度较大如果学习起来感觉吃力可以直接学习 [请求封装-使用 npm 包发送请求] 以后的模块 01. 为什么要封装 wx.request 小程序大多数 API 都是异步 API如 wx.request()wx.login() 等。这类 API 接口通常都接收一个 Object 对象类型的参数参数中可以按需指定以下字段来接收接口调用结果 参数名类型必填说明successfunction否调用成功的回调函数failfunction否调用失败的回调函数completefunction否调用结束的回调函数调用成功、失败都会执行 wx.request({// 接口调用成功的回调函数success() {wx.request({success() {wx.request({success() {wx.request({success() {wx.request({success() {wx.request({success() {wx.request({success() {wx.request({success() {}})}})}})}})}})}})}})},// 接口调用失败的回调函数fail() {},// 接口调用结束的回调函数调用成功、失败都会执行complete() {} }) 如果采用这种回调函数的方法接收返回的值可能会出现多层 success 套用的情况容易出现回调地狱问题 为了解决这个问题小程序基础库从 2.10.2 版本起异步 API 支持 callback promise 两种调用方式。 当接口参数 Object 对象中不包含 success/fail/complete 时将默认返回 promise否则仍按回调方式执行无返回值。 但是部分接口如 downloadFile, request, uploadFile 等本身就有返回值因此不支持 promise 调用方式它们的 promisify 需要开发者自行封装。 Axios 是我们日常开发中常用的一个基于 promise 的网络请求库 我们可以参考 Axios 的 [使用方式] 来封装自己的网络请求模块咱们看一下使用的方式 网络请求模块封装 import WxRequest from mina-request// 自定义配置新建一个实例 const instance new WxRequest(({baseURL: https://some-domain.com/api/,timeout: 1000,headers: {X-Custom-Header: foobar} })// 通过 instance.request(config) 方式发起网络请求 instance.requst({method: post,url: /user/12345,data: {firstName: Fred,lastName: Flintstone} })// 通过 instance.get 方式发起网络请求 instance.get(url, data, config)// 通过 instance.delete 方式发起网络请求 instance.delete(url, data, config)// 通过 instance.post 方式发起网络请求 instance.post(url, data, config)// 通过 instance.put 方式发起网络请求 instance.put(url, data, config)// ----------------------------------------------// 添加请求拦截器 instance.interceptors.request (config) {// 在发送请求之前做些什么return config }// 添加响应拦截器 instance.interceptors.response (response) {// response.isSuccess true代码执行了 wx.request 的 success 回调函数// response.isSuccess false代码执行了 wx.request 的 fail 回调函数// response.statusCode // http 响应状态码// response.config // 网络请求请求参数// response.data 服务器响应的真正数据// 对响应数据做点什么return response } 封装后网络请求模块包含以下功能 包含 request 实例方法发送请求包含 get、delete、put、post 等实例方法可以快捷的发送网络请求包含 请求拦截器、响应拦截器包含 uploadFile 将本地资源上传到服务器 API包含 all 并发请求方法同时优化了并发请求时 loading 显示效果 02. 请求封装-request 方法 思路分析 在封装网络请求模块的时候采用 Class 类来进行封装采用类的方式封装代码更具可复用性也方便地添加新的方法和属性提高代码的扩展性 我们先创建一个 class 类同时定义 constructor 构造函数 // 创建 WxRequest 类 class WxRequest {constructor() {} }我们在 WxRequest 类内部封装一个 request 实例方法 request 实例方法中需要使用 Promise 封装 wx.request也就是使用 Promise 处理 wx.request 的返回结果 request 实例方法接收一个 options 对象作为形参options 参数和调用 wx.request 时传递的请求配置项一致 接口调用成功时通过 resolve 返回响应数据接口调用失败时通过 reject 返回错误原因 class WxRequest {// 定义 constructor 构造函数用于创建和初始化类的属性和方法constructor() {}/*** description 发起请求的方法* param { Object} options 请求配置选项同 wx.request 请求配置选项* returns Promise*/request(options) {// 使用 Promise 封装异步请求return new Promise((resolve, reject) {// 使用 wx.request 发起请求wx.request({...options,// 接口调用成功的回调函数success: (res) {resolve(res)},// 接口调用失败的回调函数fail: (err) {reject(err)}})})} }然后对 WxRequest 进行实例化然后测试 request 实例方法是否封装成功 注意我们先将类 和 实例化的对象放到同一个文件中这样方便进行调试后面我们在拆分成两个文件 class WxRequest {// coding.... }// ----------------- 实例化 ----------------------// 对 WxRequest 进行实例化 const instance new WxRequest()// 将 WxRequest 的实例通过模块化的方式暴露出去 export default instance 在其他模块中引入封装的文件后我们期待通过 request() 方式发起请求以 promise 的方式返回参数 // 导入创建的实例 import instance from ../../utils/wx-requestPage({// 点击按钮触发 handler 方法async handler() {// 通过实例调用 request 方法发送请求const res await instance.request({url: https://gmall-prod.atguigu.cn/mall-api/index/findBanner,method: GET})console.log(res)} }) 落地代码 ➡️ /utils/request.js // 创建 WxRequest 类采用类的方式进行封装会让方法更具有复用性也可以方便进行添加新的属性和方法class WxRequest {// 定义 constructor 构造函数用于创建和初始化类的属性和方法constructor() {}/*** description 发起请求的方法* param { Object} options 请求配置选项同 wx.request 请求配置选项* returns Promise*/request(options) {// 使用 Promise 封装异步请求return new Promise((resolve, reject) {// 使用 wx.request 发起请求wx.request({...options,// 接口调用成功的回调函数success: (res) {resolve(res)},// 接口调用失败的回调函数fail: (err) {reject(err)}})})} }// ----------------- 实例化 ----------------------// 对 WxRequest 进行实例化 const instance new WxRequest()// 将 WxRequest 的实例通过模块化的方式暴露出去 export default instance ➡️ /pages/test/test.js import instance from ../../utils/requestPage({// 点击按钮触发 handler 方法async handler() {// 第一种调用方式通过 then 和 catch 接收返回的值// instance// .request({// url: https://gmall-prod.atguigu.cn/mall-api/index/findBanner,// method: GET// })// .then((res) {// console.log(res)// })// .catch((err) {// console.log(err)// })// 第二种调用方式通过 await 和 async 接收返回的值const res await instance.request({url: https://gmall-prod.atguigu.cn/mall-api/index/findBanner,method: GET})console.log(res)}}) 03. 请求封装-设置请求参数 思路分析 在发起网络请求时需要配置一些请求参数 其中有一些参数我们可以设置为默认参数例如请求方法、超时时长 等等因此我们在封装时我们要定义一些默认的参数。 // 默认参数对象 defaults {baseURL: , // 请求基准地址url: , // 开发者服务器接口地址data: null, // 请求参数method: GET,// 默认请求方法// 请求头header: {Content-type: application/json // 设置数据的交互格式},timeout: 60000 // 小程序默认超时时间是 60000一分钟// 其他参数... }但是不同的项目请求参数的设置是不同的我们还需要允许在进行实例化的时候传入参数对默认的参数进行修改。例如 // 对 WxRequest 进行实例化 const instance new WxRequest({baseURL: https://gmall-prod.atguigu.cn/mall-api, // 请求基准地址timeout: 10000 // 微信小程序 timeout 默认值为 60000 }) 在通过实例调用 request 实例方法时也会传入相关的请求参数 const res await instance.request({url: /index/findBanner,method: GET })从而得出结论请求参数的设置有三种方式 默认参数在 WxRequest 类中添加 defaults 实例属性来设置默认值实例化时参数在对 WxRequest 类进行实例化时传入相关的参数需要在 constructor 构造函数形参进行接收调用实例方法时传入请求参数 默认参数和自定义参数的合并操作通常会在constructor中进行。 因此我们就在 constructor 中将开发者传入的相关参数和defaults 默认值进行合并需要传入的配置项覆盖默认配置项 class WxRequest { // 默认参数对象defaults {baseURL: , // 请求基准地址url: , // 开发者服务器接口地址data: null, // 请求参数method: GET,// 默认请求方法// 请求头header: {Content-type: application/json // 设置数据的交互格式},timeout: 60000 // 小程序默认超时时间是 60000一分钟}/*** description 定义 constructor 构造函数用于创建和初始化类的属性和方法* param {*} params 用户传入的请求配置项*/constructor(params {}) {// 在实例化时传入的参数能够被 constructor 进行接收console.log(params) // 使用 Object.assign 合并默认参数以及传递的请求参数this.defaults Object.assign({}, this.defaults, params)}// coding.... }// ----------------- 实例化 ----------------------// 对 WxRequest 进行实例化const instance new WxRequest({baseURL: https://gmall-prod.atguigu.cn/mall-api,timeout: 15000})// 将 WxRequest 的实例通过模块化的方式暴露出去 export default instance 在调用 request 实例时也会传入相关的参数是发起请求真正的参数 我们需要将调用 reqeust 实例方法时传入的参数继续覆盖合并以后的参数请求才能够发送成功 注意让使用传入的参数覆盖默认的参数同时拼接完整的请求地址。 // 创建 request 请求方法 request(options) {// 拼接完整的请求地址options.url this.defaults.baseURL options.url// 合并请求参数options { ...this.defaults, ...options }return new Promise((resolve, reject) {// coding...})}落地代码 ➡️ utils/request.js // 创建 Request 类用于封装 wx.request() 方法 class WxRequest { // 默认参数对象defaults {baseURL: , // 请求基准地址url: , // 开发者服务器接口地址data: null, // 请求参数method: GET,// 默认请求方法// 请求头header: {Content-type: application/json // 设置数据的交互格式},timeout: 60000 // 小程序默认超时时间是 60000一分钟} /*** description 定义 constructor 构造函数用于创建和初始化类的属性和方法* param {*} params 用户传入的请求配置项*/constructor(params {}) {// 在实例化时传入的参数能够被 constructor 进行接收console.log(params) // 使用 Object.assign 合并默认参数以及传递的请求参数this.defaults Object.assign({}, this.defaults, params)}/*** description 发起请求的方法* param { Object} options 请求配置选项同 wx.request 请求配置选项* returns Promise*/request(options) {// 拼接完整的请求地址options.url this.defaults.baseURL options.url// 合并请求参数options { ...this.defaults, ...options }// 方法返回一个 Promise 对象return new Promise((resolve, reject) {// coding...})} }// ----------------- 实例化 ----------------------// 对 WxRequest 进行实例化 const instance new WxRequest({baseURL: https://gmall-prod.atguigu.cn/mall-api,timeout: 15000 })// 将 WxRequest 的实例通过模块化的方式暴露出去 export default instance 04. 请求封装-封装请求快捷方法 思路分析 目前已经完成了 request() 请求方法的封装同时处理了请求参数。 每次发送请求时都使用 request() 方法即可但是项目中的接口地址有很多不是很简洁 const res await instance.request({url: /index/findBanner,method: GET })所以我们在 request() 基础上封装一些快捷方法简化 request() 的调用。 需要封装 4 个快捷方法分别是 get、delete、post、put他们的调用方式如下 instance.get(请求地址, 请求参数, 请求配置) instance.delete(请求地址, 请求参数, 请求配置) instance.post(请求地址, 请求参数, 请求配置) instance.put(请求地址, 请求参数, 请求配置)这 4 个请求方法都是通过实例化的方式进行调用所以需要 Request 类中暴露出来 get、delete、post、put 方法。每个方法接收三个参数分别是接口地址、请求参数以及其他参数。 这 4 个快捷方法本质上其实还是调用 request 方法我们只要在方法内部组织好参数调用 request 发送请求即可 class WxRequest {// coding... // 封装 GET 实例方法get(url, data {}, config {}) {return this.request(Object.assign({ url, data, method: GET }, config))} // 封装 POST 实例方法post(url, data {}, config {}) {return this.request(Object.assign({ url, data, method: POST }, config))} // 封装 PUT 实例方法put(url, data {}, config {}) {return this.request(Object.assign({ url, data, method: PUT }, config))} // 封装 DELETE 实例方法delete(url, data {}, config {}) {return this.request(Object.assign({ url, data, method: DELETE }, config))} }// ----------------- 实例化 ----------------------// 对 WxRequest 进行实例化 const instance new WxRequest({baseURL: https://gmall-prod.atguigu.cn/mall-api,timeout: 15000 })// 将 WxRequest 的实例通过模块化的方式暴露出去 export default instance 落地代码 ➡️ utils/request.js class WxRequest {// coding... // 封装 GET 实例方法get(url, data {}, config {}) {return this.request(Object.assign({ url, data, method: GET }, config))} // 封装 POST 实例方法post(url, data {}, config {}) {return this.request(Object.assign({ url, data, method: POST }, config))} // 封装 PUT 实例方法put(url, data {}, config {}) {return this.request(Object.assign({ url, data, method: PUT }, config))} // 封装 DELETE 实例方法delete(url, data {}, config {}) {return this.request(Object.assign({ url, data, method: DELETE }, config))} }// ----------------- 实例化 ----------------------// 对 WxRequest 进行实例化 const instance new WxRequest({baseURL: https://gmall-prod.atguigu.cn/mall-api,timeout: 15000 })// 将 WxRequest 的实例通过模块化的方式暴露出去 export default instance ➡️ /pages/test/test.js // 导入创建的实例 import instance from ../../utils/wx-requestPage({async handler() {// 第一种调用方式通过 then 和 catch 接收返回的值// instance// .request({// url: https://gmall-prod.atguigu.cn/mall-api/index/findBanner,// method: GET// })// .then((res) {// console.log(res)// })// .catch((err) {// console.log(err)// })// 第二种调用方式// 通过实例调用 request 方法发送请求// const res await instance.request({// url: /index/findBanner,// method: GET// })// console.log(res)// 第三种调用方式通过调用快捷方式接收返回的值const res await instance.get(/index/findBanner)console.log(res)} }) 05. 请求封装-wx.request 注意事项 知识点 在使用 wx.request 发送网络请求时。 只要成功接收到服务器返回无论statusCode是多少都会进入 success 回调 开发者根据业务逻辑对返回值进行判断。 什么时候会有 fail 回调函数 一般只有网络出现异常、请求超时等时候才会走 fail 回调 落地代码 测试代码 request() {wx.request({url: https://gmall-prod.atguigu.cn/mall-api/index/findCategory,method: GET,// timeout: 100, 测试网络超时需要调整网络success: (res) {console.log(只要成功接收到服务器返回不管状态是多少都会进入 success 回调)console.log(res)},fail: (err) {console.log(err)}}) }06. 请求封装-定义请求/响应拦截器 思路分析 为了方便统一处理请求参数以及服务器响应结果为 WxRequest 添加拦截器功能拦截器包括 请求拦截器 和 响应拦截器 请求拦截器本质上是在请求之前调用的函数用来对请求参数进行新增和修改 响应拦截器本质上是在响应之后调用的函数用来对响应数据做点什么 注意不管成功响应还是失败响应都会执行响应拦截器 拦截器的使用方式 // 请求拦截器 instance.interceptors.request (config) {// 在发送请求之前做些什么return config }// 响应拦截器 instance.interceptors.response (response) {// 对响应数据做点什么return response } 通过使用方式我们可以得出结论 可以在 WxRequest 类内部定义 interceptors 实例属性属性中需要包含 request 以及 response 方法 需要注意在发送请求时还需要区分是否通过实例调用了拦截器 没有通过实例调用拦截器需要定义默认拦截器在默认拦截器中需要将请求参数进行返回通过实例调用拦截器那么实例调用的拦截器会覆盖默认的拦截器方法然后将新增或修改的请求参数进行返回 实现拦截器的思路 在 WxRequest 类内部定义 interceptors 实例属性属性中需要包含 request 以及 response 方法是否通过实例调用了拦截器 是定义默认拦截器否实例调用的拦截器覆盖默认拦截器 在发送请求之前调用请求拦截器在服务器响应以后调用响应拦截器 不管成功、失败响应都需要调用响应拦截器 在 WxRequest 类内部定义 interceptors 实例属性属性中需要包含 request 以及 response 方法。 没有使用拦截器定义默认拦截器需要将默认的请求参数进行返回。 如果使用了拦截器那么使用者的拦截器会覆盖默认的拦截器方法 class WxRequest {// coding... // 定义拦截器对象包含请求拦截器和响应拦截器方法方便在请求或响应之前进行处理。interceptors {// 请求拦截器request: (config) config,// 响应拦截器response: (response) response}// 用于创建和初始化类的属性以及方法// 在实例化时传入的参数会被 constructor 形参进行接收constructor(options {}) {// coding...} } // ----------------- 以下是实例化的代码 -------------------- // 目前写到同一个文件中是为了方便进行测试以后会提取成多个文件// 对 WxRequest 进行实例化 const instance new WxRequest({baseURL: https://gmall-prod.atguigu.cn/mall-api,timeout: 15000 }) // 配置请求拦截器instance.interceptors.request (config) {// 在发送请求之前做些什么return config} // 响应拦截器instance.interceptors.response (response) {// 对响应数据做点什么return response}// 将 WxRequest 实例进行暴露出去方便在其他文件中进行使用 export default instance 在发送请求之前调用请求拦截器在服务器响应以后调用响应拦截器 不管成功、失败都需要调用响应拦截器 class WxRequest {// coding...// request 实例方法接收一个对象类型的参数// 属性值和 wx.request 方法调用时传递的参数保持一致request(options) {// 注意需要先合并完整的请求地址 (baseURL url)// https://gmall-prod.atguigu.cn/mall-api/index/findBanneroptions.url this.defaults.baseURL options.url// 合并请求参数options { ...this.defaults, ...options } // 在发送请求之前调用请求拦截器options this.interceptors.request(options)// 需要使用 Promise 封装 wx.request处理异步请求return new Promise((resolve, reject) {wx.request({...options,// 当接口调用成功时会触发 success 回调函数success: (res) {// 不管接口成功还是失败都需要调用响应拦截器// 第一个参数需要合并的目标对象// 第二个参数服务器响应的数据// 第三个参数请求配置以及自定义的属性const mergetRes Object.assign({}, res, { config: options })resolve(this.interceptors.response(mergetRes))},// 当接口调用失败时会触发 fail 回调函数fail: (err) {// 不管接口成功还是失败都需要调用响应拦截器const mergetErr Object.assign({}, err, { config: options })reject(this.interceptors.response(mergetErr))}})})}// coding... }落地代码 ➡️ utils/request.js // 创建 WxRequest 类 // 通过类的方式来进行封装会让代码更加具有复用性 // 也可以方便添加新的属性和方法class WxRequest {// 定义实例属性用来设置默认请求参数defaults {baseURL: , // 请求基准地址url: , // 接口的请求路径data: null, // 请求参数method: GET, // 默认的请求方法// 请求头header: {Content-type: application/json // 设置数据的交互格式},timeout: 60000 // 默认的超时时长小程序默认的超时时长是 1 分钟} // 定义拦截器对象包含请求拦截器和响应拦截器方法方便在请求或响应之前进行处理。interceptors {// 请求拦截器request: (config) config,// 响应拦截器response: (response) response}// 用于创建和初始化类的属性以及方法// 在实例化时传入的参数会被 constructor 形参进行接收constructor(params {}) {// 通过 Object.assign 方法合并请求参数// 注意需要传入的参数覆盖默认的参数因此传入的参数需要放到最后this.defaults Object.assign({}, this.defaults, params)}// request 实例方法接收一个对象类型的参数// 属性值和 wx.request 方法调用时传递的参数保持一致request(options) {// 注意需要先合并完整的请求地址 (baseURL url)// https://gmall-prod.atguigu.cn/mall-api/index/findBanneroptions.url this.defaults.baseURL options.url// 合并请求参数options { ...this.defaults, ...options } // 在发送请求之前调用请求拦截器options this.interceptors.request(options)// 需要使用 Promise 封装 wx.request处理异步请求return new Promise((resolve, reject) {wx.request({...options,// 当接口调用成功时会触发 success 回调函数success: (res) {// 不管接口成功还是失败都需要调用响应拦截器// 第一个参数需要合并的目标对象// 第二个参数服务器响应的数据// 第三个参数请求配置以及自定义的属性const mergeRes Object.assign({}, res, { config: options })resolve(this.interceptors.response(mergeRes))},// 当接口调用失败时会触发 fail 回调函数fail: (err) {// 不管接口成功还是失败都需要调用响应拦截器const mergeErr Object.assign({}, err, { iconfig: options })// 不管接口成功还是失败都需要调用响应拦截器err this.interceptors.response(mergeErr)reject(err)}})})}// 封装 GET 实例方法get(url, data {}, config {}) {// 需要调用 request 请求方法发送请求只需要组织好参数传递给 request 请求方法即可// 当调用 get 方法时需要将 request 方法的返回值 return 出去return this.request(Object.assign({ url, data, method: GET }, config))}// 封装 DELETE 实例方法delete(url, data {}, config {}) {return this.request(Object.assign({ url, data, method: DELETE }, config))}// 封装 POST 实例方法post(url, data {}, config {}) {return this.request(Object.assign({ url, data, method: POST }, config))}// 封装 PUT 实例方法put(url, data {}, config {}) {return this.request(Object.assign({ url, data, method: PUT }, config))} }// ----------------- 以下是实例化的代码 -------------------- // 目前写到同一个文件中是为了方便进行测试以后会提取成多个文件// 对 WxRequest 进行实例化 const instance new WxRequest({baseURL: https://gmall-prod.atguigu.cn/mall-api,timeout: 15000 }) // 配置请求拦截器instance.interceptors.request (config) {// 在发送请求之前做些什么return config} // 响应拦截器instance.interceptors.response (response) {// 对响应数据做点什么return response.data}// 将 WxRequest 实例进行暴露出去方便在其他文件中进行使用 export default instance 07. 请求封装-完善请求/响应拦截器 思路分析 在响应拦截器我们需要判断是请求成功还是请求失败然后进行不同的业务逻辑处理。 例如请求成功以后将数据简化返回网络出现异常则给用户进行网络异常提示。 目前不管请求成功 (success)还是请求失败fail都会执行响应拦截器 那么怎么判断是请求成功还是请求失败呢 封装需求 如果请求成功将响应成功的数据传递给响应拦截器同时在传递的数据中新增 isSuccess: true 字段表示请求成功如果请求失败将响应失败的数据传递给响应拦截器同时在传递的数据中新增 isSuccess: false 字段表示请求失败 在实例调用的响应拦截中根据传递的数据进行以下的处理 如果isSuccess: true 表示服务器响应了结果我们可以将服务器响应的数据简化以后进行返回如果isSuccess: false 表示是网络超时或其他网络问题提示 网络异常同时将返回即可 落地代码 ➡️ utils/request.js class WxRequest {// coding....request(options) {// coding....// 使用 Promise 封装异步请求return new Promise((resolve, reject) {// 使用 wx.request 发起请求wx.request({...options,// 接口调用成功的回调函数success: (res) {// 响应成功以后触发响应拦截器if (this.interceptors.response) {// 调用响应拦截器方法获取到响应拦截器内部返回数据// success: true 表示服务器成功响应了结果我们需要对业务状态码进行判断res this.interceptors.response({ response: res, isSuccess: true })}// 将数据通过 resolve 进行返回即可resolve(res)},// 接口调用失败的回调函数fail: (err) {// 响应失败以后也要执行响应拦截器if (this.interceptors.response) {// isSuccess: false 表示是网络超时或其他问题err this.interceptors.response({ response: err, isSuccess: true })}// 当请求失败以后通过 reject 返回错误原因reject(err)}})})}// coding...... }// -----------------------------------------------------// 对 WxRequest 进行实例化 const instance new WxRequest({baseURL: https://gmall-prod.atguigu.cn/mall-api })// 设置请求拦截器 instance.setRequestInterceptor((config) {console.log(执行请求拦截器)return config })// 设置响应拦截器instance.setResponseInterceptor((response) {const { response: res, isSuccess } response // isSuccess: false 表示是网络超时或其他问题提示 网络异常同时将返回即可if (!isSuccess) {wx.toast(网络异常请稍后重试~)// 如果请求错误将错误的结果返回出去return res} // 简化数据return response.data })// 将 WxRequest 的实例通过模块化的方式暴露出去 export default instance 08. 请求封装-使用请求/响应拦截器 思路分析 使用请求拦截器 在发送请求时购物车列表、收货地址、更新头像等接口都需要进行权限验证因此我们需要在请求拦截器中判断本地是否存在访问令牌 token 如果存在就需要在请求头中添加 token 字段。 使用响应拦截器 在使用 wx.request 发送网络请求时。只要成功接收到服务器返回无论statusCode是多少都会进入 success 回调。 因此开发者根据业务逻辑对返回值进行判断。 后端返回的业务状态码如下 业务状态码 200 说明接口请求成功服务器成功返回了数据业务状态码 208 说明没有 token 或者 token 过期失效需要登录或者重新登录业务状态码 其他说明请求或者响应出现了异常 其他测试接口/cart/getCartList 落地代码 ➡️ utils/request.js // 创建 WxRequest 类采用类的方式进行封装会让方法更具有复用性也可以方便进行添加新的属性和方法class WxRequest {// coding... }// -----------------------------------------------------// 对 WxRequest 进行实例化 const instance new WxRequest({baseURL: https://gmall-prod.atguigu.cn/mall-api,timeout: 5000 })// 设置请求拦截器 instance.setRequestInterceptor((config) {// 从本地获取 tokenif (wx.getStorageSync(token)) {// 如果存在 token 则添加请求头config.header[token] wx.getStorageSync(token)}// 返回请求参数return config })// 设置响应拦截器 instance.setResponseInterceptor(async (response) {const { response: res, isSuccess } response // isSuccess: false 表示是网络超时或其他问题提示 网络异常同时将返回即可if (!isSuccess) {wx.toast(网络异常请稍后重试~)// 如果请求错误将错误的结果返回出去return res} switch (res.data.code) {case 200:return res.data case 208:// 判断用户是否点击了确定const modalStatus await wx.modal({title: 提示,content: 登录授权过期请重新授权}) // 如果点击了确定先清空本地的 token然后跳转到登录页面if (modalStatus) {wx.clearStorageSync()wx.navigateTo({url: /pages/login/login})}return default:wx.showToast({title: 接口调用失败~~~~,icon: none}) // 将错误继续向下传递return Promise.reject(response)} })// 将 WxRequest 的实例通过模块化的方式暴露出去 export default instance 09. 请求封装-添加并发请求 思路分析 前端并发请求是指在前端页面同时向后端发起多个请求的情况。当一个页面需要请求多个接口获取数据时为了提高页面的加载速度和用户体验可以同时发起多个请求这些请求之间就是并发的关系。 我们通过两种方式演示发起多个请求 使用 async 和 await 方式使用 Promise.all() 方式 首先使用async 和 await 方式发送请求使用 async 和 await 能够控制异步任务以同步的流程执行代码如下这时候就会产生一个问题当第一个请求执行完以后才能执行第二个请求这样就会造成请求的阻塞影响渲染的速度如下图 这时候我们需要使用 Promise.all() 方式同时发起多个异步请求并在所有请求完成后再进行数据处理和渲染。使用Promise.all() 能够将多个请求同时发出不会造成请求的阻塞。 通过两种方式演示我们能够知道封装并发请求的必要性。在 WxRequest 实例中封装 all 方法使用展开运算符将传入的参数转成数组方法的内部使用 Promise.all() 接收传递的多个异步请求将处理的结果返回即可。 class WxRequest {// coding... // 封装处理并发请求的 all 方法all(...promise) {return Promise.all(promise)}// coding... }// coding... 落地代码 ➡️ utils/request.js class WxRequest {// coding... // 封装处理并发请求的 all 方法all(...promise) {return Promise.all(promise)}// coding... }// coding... ➡️ /pages/test/test.js import instance from ../../utils/httpPage({async getData() {// 使用 Promise.all 同时处理多个异步请求const [res1, res2] await instance.all([instance.get(/mall-api/index/findBanner),instance.get(/mall-api/index/findCategory1)])console.log(res1)console.log(res2)} }) 10. 请求封装-添加 loading 思路分析 在封装时添加 loading 效果从而提高用户使用体验 在请求发送之前需要通过 wx.showLoading 展示 loading 效果 当服务器响应数据以后需要调用 wx.hideLoading 隐藏 loading 效果 要不要加 loading 添加到 WxRequest 内部 在类内部进行添加方便多个项目直接使用类提供的 loading 效果也方便统一优化 wx.showLoading 使用体验。 但是不方便自己来进行 loading 个性化定制。 如果想自己来控制 loading 效果带来更丰富的交互体验就不需要将 loading 封装到类内部但是需要开发者自己来优化 wx.showLoading 使用体验每个项目都要写一份。 大伙可以按照自己的业务需求进行封装 在项目中我们会选择第一种方式。折中 不过也会通过属性控制是否展示 loading从而方便类使用者自己控制 loading 显示 落地代码 ➡️ utils/request.js class WxRequest {// coding...constructor(options {}) {// coding...}// 创建 request 请求方法request(options) {// 拼接完整的请求地址options.url this.defaults.baseURL options.url// 合并请求参数options { ...this.defaults, ...options } // 发送请求之前添加 lodingwx.showLoading()// 如果存在请求拦截器我们则调用请求拦截器if (this.interceptors.request) {// 请求之前触发请求拦截器options this.interceptors.request(options)}// 方法返回一个 Promise 对象return new Promise((resolve, reject) {wx.request({...options,success: (res) {// coding...},fail: (err) {// coding...},complete: () {// 接口调用完成后隐藏 lodingwx.hideLoading()}})})}// coding... } 11. 请求封装-完善 loading 思路分析 目前在发送请求时请求发送之前会展示 loading响应以后会隐藏 loading。 但是 loading 的展示和隐藏会存在以下问题 每次请求都会执行 wx.showLoading()但是页面中只会显示一个后面的 loading会将前面的覆盖同时发起多次请求只要有一个请求成功响应就会调用 wx.hideLoading导致其他请求还没完成也不会 loading请求过快 或 一个请求在另一个请求后立即触发这时候会出现 loading 闪烁问题 我们通过 队列 的方式解决这三个问题首先在类中新增一个实例属性 queue初始值是一个空数组 发起请求之前判断 queue 如果是空数组则显示 loading 然后立即向queue新增请求标识在 complete 中每次请求成功结束从 queue 中移除一个请求标识queue 为空时隐藏 loading为了解决网络请求过快产生loading 闪烁问题可以使用定时器来做判断即可 落地代码 ➡️ utils/request.js class WxRequest {// coding...constructor(options {}) {// 使用 Object.assign 合并默认参数以及传递的请求参数this.defaults Object.assign({}, this.defaults, options)// 定义拦截器对象包含请求拦截器和响应拦截器方法方便在请求或响应之前进行处理。this.interceptors {// 请求拦截器request: null,// 响应拦截器response: null} // 初始化 queue 数组用于存储请求队列this.queue []}// 创建 request 请求方法request(options) {// 如果有新的请求则清空上一次的定时器this.timerId clearTimeout(this.timerId)// 拼接完整的请求地址options.url this.defaults.baseURL options.url// 合并请求参数options { ...this.defaults, ...options }// 如果存在请求拦截器我们则调用请求拦截器if (this.interceptors.request) {// 请求之前触发请求拦截器options this.interceptors.request(options)} // 发送请求之前添加 lodingthis.queue.length 0 wx.showLoading()// 然后想队列中添加 request 标识代表需要发送一次新请求this.queue.push(request)// 方法返回一个 Promise 对象return new Promise((resolve, reject) {wx.request({...options,success: (res) {// coding...},fail: (err) {// coding...},complete: () {// 接口调用完成后隐藏 loding// wx.hideLoading() // 每次请求结束后从队列中删除一个请求标识this.queue.pop()// 如果队列已经清空在往队列中添加一个标识this.queue.length 0 this.queue.push(request) // 等所有的任务执行完以后经过 100 毫秒// 将最后一个 request 清除然后隐藏 loadingthis.timerId setTimeout(() {this.queue.pop()this.queue.length 0 wx.hideLoading()}, 100)}})})}// 封装快捷请求方法// coding...// 封装拦截器// coding... }// coding...export default instance 12. 请求封装-控制 loading 显示 思路分析 在我们封装的网络请求文件中通过 wx.showLoading 默认显示了 loading 效果 但是在实际开发中有的接口可能不需要显示 loading 效果或者开发者希望自己来控制 loading 的样式与交互那么就需要关闭默认 loading 效果。 这时候我们就需要一个开关来控制 loading 显示。 类内部设置默认请求参数 isLoading 属性默认值是 true在类内部根据 isLoading 属性做判断即可某个接口不需要显示 loading 效果可以在发送请求的时候可以新增请求配置 isLoading 设置为 false整个项目都不需要显示loading 效果可以在实例化的时候传入 isLoading 配置为 false 实现步骤 在 WxRequest 类的默认请求配置项中设置 isLoading 默认值为 true显示 loading class WxRequest {// 初始化默认的请求属性defaults {url: , // 开发者服务器接口地址data: null, // 请求参数header: {}, // 设置请求的 headertimeout: 60000, // 超时时间method: GET, // 请求方式isLoading: true // 是否显示 loading 提示框}// code... }在进行实例化的时候可以配置 isLoading 配置为 false隐藏 loading // 对 WxRequest 进行实例化 const instance new WxRequest({baseURL: https://gmall-prod.atguigu.cn/mall-api,isLoading: false // 隐藏 loading })在发送网络请求时候传入请求配置 isLoading 配置为 false隐藏 loading async func() {// 请求配置 isLoading 配置为 false隐藏 loadingawait instance.get(/index/findCategory1, null, { isLoading: true }) }wx-request 内部代码实现 // 创建 WxRequest 类采用类的方式进行封装会让方法更具有复用性也可以方便进行添加新的属性和方法class WxRequest {// 初始化默认的请求属性defaults {url: , // 开发者服务器接口地址data: null, // 请求参数header: {}, // 设置请求的 headertimeout: 60000, // 超时时间method: GET, // 请求方式isLoading: true // 是否显示 loading 提示框}constructor(params {}) {// coding...}request(options) {// coding... // 发送请求之前添加 lodingif (options.isLoading) {this.queue.length 0 wx.showLoading()// 然后想队列中添加 request 标识代表需要发送一次新请求this.queue.push(request)}// 请求之前触发请求拦截器// 如果存在请求拦截器则触发请求拦截器if (this.interceptors.request) {options this.interceptors.request(options)}// 使用 Promise 封装异步请求return new Promise((resolve, reject) {// 使用 wx.request 发起请求wx.request({...options,// 接口调用成功的回调函数success: (res) {// coding...},// 接口调用失败的回调函数fail: (err) {// coding...},complete: () {// 接口调用完成后隐藏 loding// wx.hideLoading() if (!options.isLoading) return// 每次请求结束后从队列中删除一个请求标识this.queue.pop()// 如果队列已经清空在往队列中添加一个标识this.queue.length 0 this.queue.push(request)// 等所有的任务执行完以后经过 100 毫秒// 将最后一个 request 清除然后隐藏 loadingthis.timerId setTimeout(() {this.queue.pop()this.queue.length 0 wx.hideLoading()}, 100)}})})}// coding... } 13. 请求封装-封装 uploadFile 思路分析 wx.uploadFile 也是我们在开发中常用的一个 API用来将本地资源上传到服务器。 例如在获取到微信头像以后将微信头像上传到公司服务器。 wx.uploadFile({url: , // 必填项开发者服务器地址filePath: , // 必填项要上传文件资源的路径 (本地路径)name: // 必填项文件对应的 key开发者在服务端可以通过这个 key 获取文件的二进制内容 })在了解了 API 以后我们直接对 wx.uploadFile 进行封装即可。 首先在 WxRequest 类内部创建 upload 实例方法实例方法接收四个属性 /** * description 文件上传接口封装 * param { string } url 文件上传地址 * param { string } filePath 要上传文件资源的路径 * param { string } name 文件对应的 key * param { string } config 其他配置项 * returns */ upload(url, filePath, name, config {}) {return this.request(Object.assign({ url, filePath, name, method: UPLOAD }, config)) } 这时候我们需要在 request 实例方法中对 method 进行判断如果是 UPLOAD则调用 wx.uploadFile 上传API // request 实例方法接收一个对象类型的参数 // 属性值和 wx.request 方法调用时传递的参数保持一致 request(options) {// coding...// 需要使用 Promise 封装 wx.request处理异步请求return new Promise((resolve, reject) {if (options.method UPLOAD) {wx.uploadFile({...options,success: (res) {// 将服务器响应的数据通过 JSON.parse 转换为 JS 对象res.data JSON.parse(res.data)const mergeRes Object.assign({}, res, {config: options,isSuccess: true})resolve(this.interceptors.response(mergeRes))},fail: (err) {const mergeErr Object.assign({}, err, {config: options,isSuccess: true})reject(this.interceptors.response(mergeErr))},complete: () {this.queue.pop()this.queue.length 0 wx.hideLoading()}})} else {wx.request({// coding...})}}) } 落地代码 ➡️ utils/request.js // request 实例方法接收一个对象类型的参数 // 属性值和 wx.request 方法调用时传递的参数保持一致 request(options) {// coding...// 需要使用 Promise 封装 wx.request处理异步请求return new Promise((resolve, reject) {if (options.method UPLOAD) {wx.uploadFile({...options,success: (res) {// 将服务器响应的数据通过 JSON.parse 转换为 JS 对象res.data JSON.parse(res.data)const mergeRes Object.assign({}, res, {config: options,isSuccess: true})resolve(this.interceptors.response(mergeRes))},fail: (err) {const mergeErr Object.assign({}, err, {config: options,isSuccess: true})reject(this.interceptors.response(mergeErr))},complete: () {this.queue.pop()this.queue.length 0 wx.hideLoading()}})} else {wx.request({// coding...})}}) } test/test.js Page({/*** 页面的初始数据*/data: {avatarUrl: ../../assets/Jerry.png},// 获取微信头像async chooseavatar(event) {// 目前获取的微信头像是临时路径// 临时路径是有失效时间的在实际开发中需要将临时路径上传到公司的服务器const { avatarUrl } event.detail// 调用 upload 方法发送请求将临时路径上传到公司的服务器const res await instance.upload(/fileUpload,event.detail.avatarUrl,file)// 将返回的数据赋值给 data 中的数据this.setData({avatarUrl: res.data})},// coding... }14. 请求封装-使用 npm 包发送请求 思路分析 封装的网络请求模块发布到了 npm 如果你在学习网络请求模块封装时感觉比较吃力可以先使用 npm 包实现功能。 npm install mina-request构建 npm ​ 安装包后需要在微信开发者工具中进行 npm 构建点击 工具 ➡️ 构建 npm 其余步骤参考文档进行开发即可 mina-request 地址 落地代码 import WxRequest from ./request; import { env } from ./env ; // 是否显示重新登录 let isRelogin { show: false }; // ----------------- 实例化 ---------------------- // 对 WxRequest 进行实例化 const instance new WxRequest({baseURL: env.baseURL,timeout: 15000, });// 配置请求拦截器 instance.interceptors.request (config) {// 在发送请求之前做些什么console.log(config, 在发送请求之前做些什么);// 从本地获取 tokenif (wx.getStorageSync(token)) {// 如果存在 token 则添加请求头config.header[token] wx.getStorageSync(token);}// 返回请求参数return config; };// 响应拦截器 instance.interceptors.response (response) {console.log(response, 响应拦截器);const { isSuccess, data } response;// isSuccess: false 表示是网络超时或其他问题提示 网络异常同时将返回即可if (!isSuccess) {wx.showToast({title: 网络异常请稍后重试~,icon: error,});// 如果请求错误将错误的结果返回出去return response;}switch (data.code) {case 200:return data;case 208:// 控制多个接口触发弹框只出现一次if (!isRelogin.show) {isRelogin.show true;wx.showModal({showCancel: false,title: 提示,content: 登录授权过期请重新授权,complete: (res) {console.log(res);// 清空tokenwx.removeStorageSync(token);// 返回首页wx.reLaunch({url: /pages/login/login,});// 点击确认后恢复状态isRelogin.show false;},});}// 将错误继续向下传递return Promise.reject(response);default:wx.showToast({title: 接口调用失败~~~~,icon: none,});// 将错误继续向下传递return Promise.reject(response);} };// 将 WxRequest 的实例通过模块化的方式暴露出去 export default instance; 15. 环境变量-小程序设置环境变量 知识点 在实际开发中不同的开发环境调用的接口地址是不一样的。 例如开发环境需要调用开发版的接口地址生产环境需要调用正式版的接口地址 这时候我们就可以使用小程序提供了 wx.getAccountInfoSync() 接口用来获取当前账号信息在账号信息中包含着 小程序 当前环境版本。 环境版本合法值开发版develop体验版trial正式版release 落地代码 // 获取当前帐号信息 const accountInfo wx.getAccountInfoSync()// 获取小程序项目的 appId console.log(accountInfo.miniProgram.appId) // 获取小程序 当前环境版本 console.log(accountInfo.miniProgram.envVersion) 根据环境的不同我们给 env 变量设置不同的请求基准路径 baseURL 然后将 env环境变量导出 // 获取 小程序帐号信息 const { miniProgram } wx.getAccountInfoSync();// 获取小程序当前开发环境 // develop 开发版, trial 体验版, release 正式版 const { envVersion } miniProgram;let env {baseURL: https://gmall-prod.atguigu.cn/mall-api, };switch (envVersion) {case develop:env.baseURL https://gmall-prod.atguigu.cn/mall-api;break;case trial:env.baseURL https://gmall-prod.atguigu.cn/mall-api;break;case release:env.baseURL https://gmall-prod.atguigu.cn/mall-api;break;default:console.log(当前环境异常);env.baseURL https://gmall-prod.atguigu.cn/mall-api; }export { env }; 16. 接口调用方式说明 思路分析 在开发中我们会将所有的网络请求方法放置在 api 目录下统一管理然后按照模块功能来划分成对应的文件在文件中将接口封装成一个个方法单独导出例如 // 导入封装的网络请求工具 http.js import http from ../utils/http/*** description 获取轮播图数据* returns Promise*/ export const reqBannerData () http.get(/index/findBanner) 这样做的有以下几点好处 易于维护一个文件就是一个模块一个方法就是一个功能清晰明了查找方便便于复用哪里使用哪里导入可以在任何一个业务组件中导入需要的方法团队合作分工合作 落地代码 // 导入封装的网络请求工具 http.js import http from ../utils/http/*** description 获取轮播图数据* returns Promise*/ export const reqSwiperData () http.get(/mall-api/index/findBanner) // 导入接口 API import { reqSwiperData } from ../../api/indexPage({// 页面数据data: {swiperList: []},// 小程序页面加载时执行onLoad () {// 调用获取首页数据的方法getHomeList()}// 获取首页数据async getHomeList() {// 获取轮播图数据const res await reqSwiperData()console.log(res)} })
http://www.zqtcl.cn/news/367834/

相关文章:

  • 知名网站建设加盟合作企业邮箱如何登录
  • asp net mvc做网站软文推广是什么
  • 张家口住房和城乡建设厅网站如何做点击赚钱的网站
  • 网站在建设中无法访问贵州碧江区住房和城乡建设局网站
  • 营销类网站 英文东莞正规的免费网站优化
  • 柳州网站推广最好的公司百度seo优化培训
  • 哈尔滨门户网站建站哪个网站做农产品
  • 网站行业关键词如何建设网站
  • wordpress插件目录504wordpress访问优化插件
  • 固定ip做网站网页源码提取工具
  • php网站模板源码下载公司网络营销推广软件
  • 免费电子版个人简历模板温州快速排名优化
  • 网站修改titlewordpress显示icp备案
  • 中国国际贸易单一窗口登录南京专业网站优化公司
  • 手机网站建设合同wordpress案例分析
  • 深圳做网站什么公司好广州电商小程序开发
  • 郑州高新区做网站的公司如何欣赏网站
  • 网站做维恩图做网站的公司杭州
  • 柳州公司网站制作公司wordpress 网店
  • 网站增加栏目费用在网站开发中如何设置登录
  • 怎样用php做网站百度推广联系人
  • 怎么建立手机网站如何申请公司域名
  • 营销型网站怎么收费邓州企业网站
  • 北京建设官方网站邢台网站维护
  • 新余网站制作网站开发工资咋样
  • 襄阳网站建设外包自己做一个网站
  • 网站域名的后缀wordpress文章归类
  • 查询企业信息的官方网站大连建设网站公司
  • 网站建设 全包专业建设规划方案模板
  • 做网站好还是做微信小程序好浙江建设工程造价信息网站