微信小程序的大部分api是 異步 的。
簡(jiǎn)單地舉個(gè):chestnut:: wx.showToast(Object object)
wx.showToast({ title: '成功', icon: 'success', duration: 2000, success: function(res) { // TODO }, fail: function(err) { // TODO } }); 復(fù)制代碼 |
事實(shí)上這樣的api 寫(xiě)的真夠好,但是對(duì)于使用者來(lái)說(shuō)并不友好。所以,為了方便同事們更加舒爽地去寫(xiě)代碼,于是我開(kāi)始琢磨封裝一個(gè)小程序api的 promisefy 的函數(shù)。
那么到底怎么封裝呢?
// defaultProps為默認(rèn)屬性,extraProps為定制化的屬性 /** * promisefy 微信內(nèi)置函數(shù) * @param fn * @return { promise } */ const promisefy = fn => defaultProps => extraProps => new Promise((resolve, reject) => fn({ ...defaultProps, ...extraProps, success: res => resolve(res), reject: err => reject(err), })); 復(fù)制代碼 |
那么到底怎么使用呢?
const showToast = promisefy(wx.showToast)({ title: '', icon: "none", duration: 2000, confirmColor: '#ff673f', mask: true }); showToast({ title: 'title' }); // 即可使用 復(fù)制代碼 |
那么這個(gè)promisefy還能怎么用呢? 1.我們可能會(huì)經(jīng)常使用storage相關(guān)的api, 那么到底是把對(duì)象JSON.stringify, 再setStorage。需要使用的時(shí)候再getStorage, 最后JSON.parse呢?當(dāng)然這是一種解決方案。如果使用promisefy,可以這樣干。
/** * * @param 需要往LocalStorage里面存數(shù)據(jù) * @returns {Promise<any[] | never>} */ const setStorage = (param = {}) => { if (!Object.keys(param).length) throw new Error('輸入的對(duì)象不為空'); return Promise.all(Object.entries(param) .map(item => promisefy(wx.setStorage)({ key: item[0], data: item[1] })())); }; setStorage({ a:1, b:2 }); 復(fù)制代碼 |
/** * * @param 需要從storage 讀取的key。 * 單個(gè)值直接傳string, 多個(gè)值傳數(shù)組 * eg. ['key1', 'key2', 'key3'] 或者 'key1' ; * @returns {key1: value1, key2: value2, key3: key3 } */ const getStorage = param => Promise.all( Object.entries(((typeof param) === 'string') ? [param] : param) .map(item => promisefy(wx.getStorage)({ key: item[1] })() .then(res => ({ [`${item[1]}`]: res.data })))) .then(res => res.reduce((prev, curr) => ({ ...prev, ...curr }), {})); getStorage('a'); // { a: 1 }, getStorage(['a', 'b']); // { a: 1, b: 2 }, 復(fù)制代碼 |
/** * @param 需要從storage 清除記錄eg. [key1, key2], key3。 */ const removeStorage = param => Promise.all( Object.entries(((typeof param) === 'string') ? [param] : param) .map(item => promisefy(wx.removeStorage)({ key: item[1] })())); removeStorage('a'); removeStorage(['a', 'b']); 復(fù)制代碼 |
2.對(duì)于有router 的頁(yè)面我們經(jīng)常會(huì)出現(xiàn)router 的三種跳轉(zhuǎn)方案。例如微信就提供了三種api:navigateTo, redirectTo ,navigateBack,這里沒(méi)有包含小程序跳小程序的api。那么我們是不是可以封裝一個(gè)公共的方法呢?
// 路徑參數(shù)的拼接 const obj2Url = params => { if (params instanceof Array || typeof params === 'number') throw new Error('跳轉(zhuǎn)參數(shù)限制于string和對(duì)象'); // 如果路徑參數(shù)為 object, 做以下轉(zhuǎn)換 if (typeof params === 'object') { const rawParams = Object.entries(params).reduce((acc, cur) => { if ((!cur[1]) && ((typeof cur[1]) !== 'boolean')) console.warn(`${cur[0]}的值為空, 請(qǐng)檢查原因!`); return `${acc + cur[0]}=${cur[1]}&`; }, ''); params = rawParams.substr(0, rawParams.length - 1); } return params; }; /** * * @param page 需要跳轉(zhuǎn)的頁(yè)面或者頁(yè)面路徑(如果是"pages/a/b/b"這樣的路徑,page='pages/a/b/b', specialUrl=true ) * @param type * @param params * @param specialUrl * @return {*} */ const jumpTo = (page = 'index', type = 'navigate', params = '', specialUrl = false) => { const { navigateTo, redirectTo, navigateBack } = wx; const types = { navigate: url => promisefy(navigateTo)({ url })(), redirect: url => promisefy(redirectTo)({ url })(), back: delta => promisefy(navigateBack)({ delta })(), }; params = obj2Url(params); console.log('**test**', 'params', params, `${page}?${params}`); if (specialUrl) return types[type](params ? `${page}?${params}` : page); // 獲取跳轉(zhuǎn)參數(shù),如果為數(shù)字,則為navigateBack,反之為 navigateTo 或 navigateBack。 const jumpPram = (typeof page === 'number') ? page : `/pages/${page}/${page}${params ? `?${params}` : ''}`; console.log(`%c**跳轉(zhuǎn)參數(shù)**jumpPram** ${jumpPram}`, 'color:white;background:green'); sendTrack(`**跳轉(zhuǎn)參數(shù)**jumpParam** ${jumpPram}`); return types[type](jumpPram); }; jumpTo('a'); // navigateTo到a頁(yè)面 jumpTo('a', 'navigate', { m: 'm' }); // navigateTo到a頁(yè)面 ,路徑參數(shù)為?m=m jumpTo('a', 'redirect', { m: 'm' }); // redirectTo到a頁(yè)面 ,路徑參數(shù)為?m=m jumpTo(1, 'redirect', { m: 'm' }); // back 上一步 ,路徑參數(shù)為?m=m 復(fù)制代碼 |
1.native 小程序開(kāi)發(fā)者。(下載babel-polyfill,導(dǎo)入regeneratorRuntime)
import regeneratorRuntime from '你放置的文件夾'; const showLoading = promisefy(wx.showLoading)({ title: '加載中', mask: true }); const hideLoading = () => wx.hideLoading(); const showMoshowToast = promisefy(wx.showToast)({ title: 'title', content: '', mask: true }); const Loading = { show: showLoading, hide: hideLoading }; const Toast = { show: showToast }; const handleErr = (e, cb) => { Loading.hide(); if ((typeof e) === 'string') { Toast.show({ title: e || '服務(wù)器異常,請(qǐng)稍后再試' }); } else { const { message } = e; Toast.show({ title: message || '服務(wù)器異常,請(qǐng)稍后再試' }); } cb && cb(); }; const fetchData = () => {} aync function() { try { await Loading.show(); const { data } = await fetchData(); this.setData({ data }) Loading.hide(); } catch (e) { handleErr(e) } } 復(fù)制代碼 |
工作日 8:30-12:00 14:30-18:00
周六及部分節(jié)假日提供值班服務(wù)