中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

用vs做網(wǎng)站如何連接數(shù)據(jù)庫最新國內(nèi)你新聞

用vs做網(wǎng)站如何連接數(shù)據(jù)庫,最新國內(nèi)你新聞,軟件開發(fā)范例的最簡單模型,wordpress 華哥文章目錄 背景整理思路V1版本V2版本V3版本 背景 最近在寫uniapp,發(fā)現(xiàn)執(zhí)行網(wǎng)絡(luò)請求的時候經(jīng)常要處理Loading效果。 比如,在發(fā)送網(wǎng)絡(luò)請求之前,觸發(fā)Loadng;無論請求成功還是失敗都要關(guān)閉Loading;請求失敗的時候我們還要…

文章目錄

  • 背景
  • 整理思路
  • V1版本
  • V2版本
  • V3版本

背景

最近在寫uniapp,發(fā)現(xiàn)執(zhí)行網(wǎng)絡(luò)請求的時候經(jīng)常要處理Loading效果。

比如,在發(fā)送網(wǎng)絡(luò)請求之前,觸發(fā)Loadng;無論請求成功還是失敗都要關(guān)閉Loading;請求失敗的時候我們還要給用戶一個友好的提示,比如“服務(wù)器打了個盹”。

每次都要手動處理,真的很麻煩;而且處理Loading的邏輯跟業(yè)務(wù)邏輯混在一起,也不便于維護。

因此,我打算把這個需求封裝成要一個方法,就叫loadingRun。

這個方法并不是一蹴而就的,經(jīng)歷了幾個版本的迭代。我強烈建議你看完這篇文章,你一定能有所收獲。

雖然是以uniapp代碼演示的,但是思路是通用的。

整理思路

在封裝之前,我們先看看封裝之前代碼長啥樣:

uni.showLoading({mask: true})
uniCloud.database().collection('orders').doc(props.orderId).get({getOne: true}).then(res => {Object.assign(order, res.result.data)uni.hideLoading()
}).catch(_ => {uni.hideLoading().then(_ => uni.showToast({icon: "fail",title: "服務(wù)器打了個盹"}))
}).finally(_ => uni.hideLoading())

有些小伙伴可能不熟悉uniapp,所以我們解釋一下部分代碼:

  • uniCloud.database().collection('orders').doc(props.orderId).get({getOne: true})這是uniapp的uniCloud的操作,執(zhí)行的是網(wǎng)絡(luò)請求,返回的是一個promise。
  • uni.showLoading() uniapp 提供的顯示Loading的api。
  • uni.hideLoading() uniapp 提供的關(guān)閉Loading的api。
  • uni.showToast() uniapp 提供的顯示Toast提示api。

這些你都可以想象成自己熟悉的UI框架的操作。

我們需要把這個方法抽成一個通用的loadingRun方法,首先不管三七二十一,我們先把這個方法寫出來:

function loadingRun() {uni.showLoading({mask: true})uniCloud.database().collection('orders').doc(props.orderId).get({getOne: true}).then(res => {Object.assign(order, res.result.data)uni.hideLoading()}).catch(_ => {uni.hideLoading().then(_ => uni.showToast({icon: "fail",title: "服務(wù)器打了個盹"}))}).finally(_ => uni.hideLoading())
}

然后我們就想,有哪些操作是可以提取出來,作為loadingRun的參數(shù)。
最容易想到的就是Object.assign(order, res.result.data)這行代碼,這行代碼是promise解決之后處理邏輯,我們可以把它提取成一個resolve參數(shù):

function loadingRun(resolve) {uni.showLoading({mask: true})uniCloud.database().collection('orders').doc(props.orderId).get({getOne: true}).then(res => {resolve(res)uni.hideLoading()}).catch(_ => {uni.hideLoading().then(_ => uni.showToast({icon: "fail",title: "服務(wù)器打了個盹"}))}).finally(_ => uni.hideLoading())
}

還有什么可以提取的呢?uniCloud.database().collection('orders').doc(props.orderId).get({getOne: true})這個操作我們可以提取,因為的網(wǎng)絡(luò)操作是不固定的。它是一個promise,我們先不管三七二十一,先用一promise來接收:

function loadingRun(promise, resolve) {uni.showLoading({mask: true})promise.then(res => {resolve(res)uni.hideLoading()}).catch(_ => {uni.hideLoading().then(_ => uni.showToast({icon: "fail",title: "服務(wù)器打了個盹"}))}).finally(_ => uni.hideLoading())
}

還能再抽嗎?貌似toast提醒的文案可以抽出來,不過我們整站的提示都是統(tǒng)一的,所以就不抽了。

現(xiàn)在就可以了嗎?顯然不是,它還有問題,有大問題,我們接著聊。

V1版本

我們前面講了封裝loadingRun的思路,就是“抽”、“抽”、“抽”,先不管合理不合理,先抽再說。這樣可以讓我們最快的得到一個基本的骨架:

function loadingRun(promise, resolve) {uni.showLoading({mask: true})promise.then(res => {resolve(res)uni.hideLoading()}).catch(_ => {uni.hideLoading().then(_ => uni.showToast({icon: "fail",title: "服務(wù)器打了個盹"}))}).finally(_ => uni.hideLoading())
}

看著不錯,實際有大問題,你知道是啥問題嗎?

問題就是loadingRun直接接收了一個promise實例。

為啥直接接收就有問題呢?因為promise是創(chuàng)建時立即執(zhí)行的,所以loadingRun執(zhí)行的時候,promise可能已經(jīng)執(zhí)行完了,網(wǎng)絡(luò)請求可能都返回了,此時在才顯示Loading,黃瓜菜都涼了。

所以loadingRun不能從外部接收一個promise,我們需要在loadingRun內(nèi)部創(chuàng)建這個promise。
我們可以讓外部傳入一個方法promiseGenerator,這個方法執(zhí)行會產(chǎn)生一個promise:

function loadingRun(promiseGenerator, resolve) {uni.showLoading({mask: true})promiseGenerator().then(res => {resolve(res)uni.hideLoading()}).catch(_ => {uni.hideLoading().then(_ => uni.showToast({icon: "fail",title: "服務(wù)器打了個盹"}))}).finally(_ => uni.hideLoading())
}

至此我們獲得了V1版本的loadingRun,我們前面代碼可以用loadingRun來重構(gòu)一下:

loadingRun(_ => uniCloud.database().collection('orders').doc(props.orderId).get({getOne: true}), res => Object.assign(order, res.result.data))

看起來沒那么清晰對吧,我們再改進一下:

// 把獲取訂單的操作封裝到一個方法中
function getOrderAsync(id) {return uniCloud.database().collection('orders').doc(id).get({getOne: true})
}
// 封裝處理邏輯
function reactiveSetOrder(res) {Object.assign(order, res.result.data)
}

現(xiàn)在的loadingRun就清晰了:

loadingRun(getOrderAsync(props.id), reactiveSetOrder)

當然后面這個封裝,不屬于我門今天討論的范疇。

V2版本

什么,還有V2版本,loadingRun還可以再優(yōu)化嗎?

還真是!現(xiàn)在的loadingRun接收一個promiseGeneratorpromiseGenerator產(chǎn)生一個promise實例。

如果我有一個很耗時的方法,但是它不返回promise,它也想用loadingRun怎么辦呢?

現(xiàn)在V1版本還不夠通用,我們需要讓它變得更加通用。

我們可以這么處理,我們把promiseGenerator參數(shù),換成更通用的func參數(shù)。如果它的結(jié)果是一個promise,那么就走原來的邏輯;否則,我們把func的執(zhí)行結(jié)果用Promise.resolve封裝成一個promise,走之前的邏輯。

這個叫參數(shù)歸一化!

我們先定一個方法判斷變量是不是一個promise:

function isPromiseLike(value) {return value != null && (typeof value === 'object' || typeof value === 'function')&& typeof value.then === 'function'
}

這里并不是直接用instanceof Promise判斷,而是判斷變量是不是滿足Promise A+規(guī)范。

接下來我們改造loadingRun

function loadingRun(func, resolve) {uni.showLoading({mask: true})let ret = func()let promise = isPromiseLike(ret) ? ret : Promise.resolve(ret)promise.then(res => {resolve(res)uni.hideLoading()}).catch(_ => {uni.hideLoading().then(_ => uni.showToast({icon: "fail",title: "服務(wù)器打了個盹"}))}).finally(_ => uni.hideLoading())
}

現(xiàn)在我們可以用loadingRun處理耗時的非promise操作了,比如計算斐波那契數(shù)列:

loadingRun(_ => fibonacciRecursive(100000), val => console.log(`計算結(jié)果:${val}`))

V3版本

啊!還能再優(yōu)化嗎?

還真實?,F(xiàn)在的loadingRun已經(jīng)夠用了,但是還有一個場景滿足不了。

比如,當網(wǎng)絡(luò)請求或者耗時操作報錯了,我希望除了提示Toast,還要執(zhí)行一個其他的操作,現(xiàn)在就沒辦法,因為promise實例沒有返回出來。

因此改造也很簡單,只需要把promise返回出來就行了。

function loadingRun(func, resolve) {uni.showLoading({ mask: true })let ret = func()let promise = isPromiseLike(ret) ? ret : Promise.resolve(ret)promise.then(res => {resolve(res)uni.hideLoading()}).catch(_ => {uni.hideLoading().then(_ => uni.showToast({icon: "fail",title: "服務(wù)器打了個盹"}))}).finally(_ => uni.hideLoading())return promise
}

然后我們就可以這樣處理:

loadingRun(getOrderAsync(props.id), reactiveSetOrder).catch(_ => doSomething())

Game Over !!!

http://www.risenshineclean.com/news/6671.html

相關(guān)文章:

  • 手機版網(wǎng)站建設(shè)百度競價包年推廣是怎么回事
  • 財政部網(wǎng)站官網(wǎng) PPP項目建設(shè)關(guān)鍵詞排名查詢網(wǎng)站
  • 網(wǎng)站建設(shè)對產(chǎn)品推銷作用大嗎百度云搜索引擎入口盤多多
  • 黑龍江建設(shè)廳網(wǎng)站官網(wǎng)做網(wǎng)站優(yōu)化哪家公司好
  • 給網(wǎng)站整一個客服 怎么做鳳凰網(wǎng)全國疫情實時動態(tài)
  • 上海網(wǎng)站建設(shè)設(shè)計公司排名無錫百度推廣開戶
  • 上海網(wǎng)站建設(shè)免費推薦上海網(wǎng)站排名優(yōu)化怎么做
  • 常用wap網(wǎng)站開發(fā)工具 手機網(wǎng)站制作軟件競價托管咨詢微競價
  • 企業(yè)做網(wǎng)站的流程某個網(wǎng)站seo分析實例
  • 網(wǎng)站開發(fā)與應(yīng)用專業(yè)最近國際新聞大事
  • 杭州做網(wǎng)站的公司哪家好網(wǎng)站優(yōu)化推廣培訓(xùn)
  • 網(wǎng)站如何發(fā)布和推廣怎么自己做一個網(wǎng)站
  • 網(wǎng)站建設(shè)前期準備衡水網(wǎng)站優(yōu)化推廣
  • 最火的做牛排沙拉網(wǎng)站深圳將進一步優(yōu)化防控措施
  • 寧波網(wǎng)站建設(shè)哪個公司好制作app平臺需要多少錢
  • 網(wǎng)站開發(fā)團隊人員青島網(wǎng)站設(shè)計
  • 醫(yī)療手機網(wǎng)站建設(shè)如皋網(wǎng)站制作
  • 自助網(wǎng)站建設(shè)程序電商軟文范例300字
  • 單頁產(chǎn)品銷售網(wǎng)站如何做推廣中國2022年重大新聞
  • 做身份證網(wǎng)站網(wǎng)站如何提交百度收錄
  • seo資源網(wǎng)站 排名登封seo公司
  • 公司官網(wǎng)網(wǎng)站如何建立sem優(yōu)化是什么
  • 梅州網(wǎng)站建seo外鏈平臺熱狗
  • 怎么做情侶網(wǎng)站百度權(quán)重是什么意思
  • 做正版電子書下載網(wǎng)站福州網(wǎng)站排名
  • 獻縣網(wǎng)站甲馬營seo網(wǎng)站優(yōu)化的
  • php做的商城網(wǎng)站設(shè)計論文網(wǎng)站排行榜查詢
  • 企業(yè)網(wǎng)站管理系統(tǒng)演示平臺查詢網(wǎng) 域名查詢
  • 禪城區(qū)建設(shè)局網(wǎng)站個人如何加入百度推廣
  • 網(wǎng)站如何做性能測試關(guān)鍵詞排名點擊軟件怎樣