小程序高级电商前端第1周走进Web全栈工程师<二>
業(yè)務(wù)對象的重要性:
?在上一次小程序高級電商前端第1周走進Web全棧工程師<一>----小程序注冊、開發(fā)工具推薦、《風(fēng)袖》首頁布局詳盡分析、Webstorm開發(fā)小程序必配配置、mock數(shù)據(jù)已經(jīng)實現(xiàn)了對于首頁頂部主題數(shù)據(jù)處理,不過目前看一下咱們請求的代碼:
這里就得啰嗦一下關(guān)于小程序代碼層級的問題了,屬于思想層面的,往往這些才是最讓自己能夠成長的東西,本身寫業(yè)務(wù)代碼并不是一個很困難的事,所以這種啰嗦是很有必要的,由于js是一種動態(tài)語言,它本身是沒有類型約束的,所以如果不給它分層那隨著業(yè)務(wù)的編寫這里面的代碼就會變得非常之臃腫不好維護,那回到咱們目前這個js文件:
很明顯它是一種頁面級別的js,而它里面的職責(zé)主要是用來控制數(shù)據(jù)綁定,也就是類似于MVC中的C層,它是View層和M業(yè)務(wù)邏輯層的一個橋梁,不應(yīng)該負(fù)責(zé)具體的業(yè)務(wù)邏輯的,所以這里分出一個M層了來,新建一個目錄:
好,接下來則需要來新建一個業(yè)務(wù)的js文件,那么接下來又得啰嗦一下了,這個業(yè)務(wù)js的文件名取名成啥呢?這里的業(yè)務(wù)叫網(wǎng)絡(luò)么?很顯然網(wǎng)絡(luò)不可能是一個業(yè)務(wù)對象,這里業(yè)務(wù)對象應(yīng)該是主題,因為請求的就是主題的數(shù)據(jù)嘛,所以咱們這樣取名:
這里一定要重視業(yè)務(wù)對象的尋找,它對于一個復(fù)雜的商用項目是很重要的,接下來咱們則來定義一個業(yè)務(wù)方法:
但是!!!這個命名也是有問題的。。好吧,一個這么簡單的東東引出這么多“思想”問題,值得么?當(dāng)然是值得的,扣得越細(xì)你的提升則越多, 你看一下這個方法名很明顯是獲取頂部的主題,貌似沒啥毛病呀,在首頁不就是頂部么?
嗯,確實是,但是!!還會有很多其它的Theme,那你咋命令呢?由于它是一個sale的主題,那這樣改唄:
也就是名字中增加了業(yè)務(wù)字段,很明顯也不太好,因為這塊位置未來是動態(tài)可以配置的,有可能還可以配優(yōu)惠券之類的,所以這里建議是像這種不要以業(yè)務(wù)來給它命名,可以給它們定義一些編號,像這樣:
嗯,不過更加好的命令應(yīng)該再加一個單詞:
因為有可能其它頁面也需要Theme,加一個頁面則會更加的清晰。
封裝HTTP請求:
接下來咱們則把網(wǎng)絡(luò)請求的代碼剪切到這個業(yè)務(wù)方法中來:
嗯,貌似很完美,但是很明顯這塊代碼有問題:
那怎么解決呢,用回調(diào),如下:
import {config} from "../config/config";class Theme {static getHomeLocationA(callback) {wx.request({url: `${config.apiBaseUrl}theme/by/names`,method: 'GET',data: {names: 't-1'},header: {Authorization: config.appKey},success: res => {callback(res.data)}})} }此時在我們的home.js的生命周期中就可以這樣來調(diào)用了,當(dāng)然啦先要將咱們新建的js導(dǎo)出一下:
調(diào)用:
編譯運行其界面顯示一切正常,那就完美了么?其實不然,雖說現(xiàn)在home.js中代碼清爽了,但是!!對于業(yè)務(wù)網(wǎng)絡(luò)請求每次還是寫起來比較麻煩,所以有必要對網(wǎng)絡(luò)請求進行一個二次封裝,以應(yīng)對未來若干個大量的業(yè)務(wù)的網(wǎng)絡(luò)請求的應(yīng)用效率:
對于網(wǎng)絡(luò)請求應(yīng)該算是一個工具類,所以咱們封裝成一個工具方法,在我們新建小程序工程時默認(rèn)IDE為我們生成了一個工具文件:
const formatTime = date => {const year = date.getFullYear()const month = date.getMonth() + 1const day = date.getDate()const hour = date.getHours()const minute = date.getMinutes()const second = date.getSeconds()return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':') }const formatNumber = n => {n = n.toString()return n[1] ? n : '0' + n }module.exports = {formatTime: formatTime }這里刪除它,對我們沒啥用,新建一個咱們自己的:
具體的代碼比較簡單,直接貼代碼了:
import {config} from "../config/config";class Http {static request(url, data, method = 'GET', callback) {wx.request({url: `${config.apiBaseUrl}${url}`,method,data,header: {Authorization: config.appKey},success: res => {callback(res.data)}})} }export {Http }接下來回到咱們的業(yè)務(wù)方法中,調(diào)用就比較簡單了:
不過這里有個細(xì)節(jié)還得優(yōu)化一下,對于方法參數(shù)的傳遞其實用這種對象的方式語義會更加的清晰:
而我們目前是直接傳遞的:
所以改造一下,比較簡單:
此時咱們就可以用對象的方式來傳遞參數(shù)了:
import {Http} from "../utils/http";class Theme {static getHomeLocationA(callback) {Http.request({url: `theme/by/names`,data: {names: 't-1'},callback: data => {callback(data)}})} }export {Theme }其實像Flutter中的命名參數(shù)也是類似的寫法,此時咱們的調(diào)用又更加簡單了,編譯運行界面一切正常。
小程序中使用async和await的難點分析:
對于上面的封裝已經(jīng)“接近”完美了,為啥說“接近”呢? 因為還有不完美的地方嘛,有兩層回調(diào),代碼顯得比較亂:
其造成有兩層回調(diào)的根據(jù)原因在于請求網(wǎng)絡(luò)是一個異步處理,而在JS中處理異步有三種方式:
- callback
這個是最常用的,但是如今用得較少了,因為代碼看著比較亂。 - promise
這個比callback要強,沒有第三種好,但是!!它是第三中的一個必備的條件。 - async await
這種也是如今比較推崇的寫法了,像Koltin、Flutter都有這樣的寫法,要能這樣寫的前提必須我們要調(diào)用的功能上返回的是promise才可以。
那咱們要用async await那直接用就成了唄,先在要執(zhí)行異步的調(diào)用前面加上await:
報紅了是因為如果一個函數(shù)內(nèi)部出現(xiàn)了await,則需要在函數(shù)聲明上加上async,如下:
但是!!!目前微信的wx.request是不會返回promise的,注意:并非只有返回promise的函數(shù)前面才能加await,其實函數(shù)返回普通的值也能加,但是加了await是沒啥意義的,只有在promise前加await才有意義, 那。。說了這么多居然用不了async await,那不是浪費表情么?當(dāng)然能用,經(jīng)過一定的包裝能讓它轉(zhuǎn)換成帶promise的函數(shù),下面就來看一下如何來轉(zhuǎn)換。
使用LinUI Promisic讓小程序內(nèi)置API支持Promise:
這里則開始對wx.request進行一下包裝達到能返回promise,進而可以使用async和await,那怎么弄呢?其實這里需要用到大神開源的LinUI組件既可解決,可以參考Promisic 回調(diào)轉(zhuǎn)換 | Lin UI,在它網(wǎng)頁前言也描述了使用的背景:
在這里先不用LinUI組件,這是開源的一個庫,需要進行安裝,為了學(xué)習(xí)的連貫性暫且先不安裝,其實也就是一個函數(shù),直接先拷到工程中來使用既可,如下:
const promisic = function (func) {return function (params = {}) {return new Promise((resolve, reject) => {const args = Object.assign(params, {success: (res) => {resolve(res);},fail: (error) => {reject(error);}});func(args);});}; };export {promisic }其中很明顯看到參數(shù)就是一個函數(shù),然后最終返回的是一個Promise:
具體的轉(zhuǎn)換細(xì)節(jié)暫且先不過多糾結(jié),先用起來,怎么用呢,其實很簡單:
此時就可以將回調(diào)給去掉了,因為咱們調(diào)用這個函數(shù)時就跟同步方法一樣了,不需要通過回調(diào)來拿結(jié)果了:
將回調(diào)函數(shù)全部替換為async和await:
接下來則可以將theme.js中的回調(diào)也改為async和await了,改法一樣:
接下來home.js中也得改寫一下了:
接下來則編譯看一下有木有問題:
報錯了。。這是因為async await是ES7的語法,而小程序現(xiàn)在是只支持ES6,要想支持ES7,則需要設(shè)置一下:
此時再編譯就木有報錯了,但是!!!圖片出不來了:
這是為啥呢?從網(wǎng)絡(luò)請求中貌似數(shù)據(jù)也正常請求下來了:
這里將結(jié)果打出來瞅一下:
編譯:
所以咱們修改一下網(wǎng)絡(luò)請求返回的結(jié)果:
這樣對于整個HTTP的請求的封裝就比較完美了。
更正:
最后再來做一個更正說明,其實在上一篇也說明過了小程序高級電商前端第1周走進Web全棧工程師<一>----小程序注冊、開發(fā)工具推薦、《風(fēng)袖》首頁布局詳盡分析、Webstorm開發(fā)小程序必配配置、mock數(shù)據(jù),這里再來說一下,因為不說明上面所寫的無法正常在本地顯示的:
同樣這篇也是去年寫的,所以。。
關(guān)注個人公眾號,獲得實時推送
總結(jié)
以上是生活随笔為你收集整理的小程序高级电商前端第1周走进Web全栈工程师<二>的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 等视距游戏 地图X和Y转换
- 下一篇: IE浏览器缓存第二次请求的解决方案