小程序模板網(wǎng)

小程序api的promisefy

發(fā)布時間:2018-12-07 08:43 所屬欄目:小程序開發(fā)教程

微信小程序的大部分api是 異步 的。

簡單地舉個:chestnut:: wx.showToast(Object object)

wx.showToast({
      title: '成功',
      icon: 'success',
      duration: 2000,
      success: function(res) { // TODO },
      fail: function(err) { // TODO }
   });
復(fù)制代碼

事實上這樣的api 寫的真夠好,但是對于使用者來說并不友好。所以,為了方便同事們更加舒爽地去寫代碼,于是我開始琢磨封裝一個小程序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ù)制代碼

那么這個promisefy還能怎么用呢? 1.我們可能會經(jīng)常使用storage相關(guān)的api, 那么到底是把對象JSON.stringify, 再setStorage。需要使用的時候再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('輸入的對象不為空');
  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。
 * 單個值直接傳string, 多個值傳數(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.對于有router 的頁面我們經(jīng)常會出現(xiàn)router 的三種跳轉(zhuǎn)方案。例如微信就提供了三種api:navigateTo, redirectTo ,navigateBack,這里沒有包含小程序跳小程序的api。那么我們是不是可以封裝一個公共的方法呢?

// 路徑參數(shù)的拼接
const obj2Url = params => {
  if (params instanceof Array || typeof params === 'number') throw new Error('跳轉(zhuǎn)參數(shù)限制于string和對象');
  // 如果路徑參數(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]}的值為空, 請檢查原因!`);
      return `${acc + cur[0]}=${cur[1]}&`;
    }, '');
    params = rawParams.substr(0, rawParams.length - 1);
  }
  return params;
};

/**
 *
 * @param page 需要跳轉(zhuǎn)的頁面或者頁面路徑(如果是"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頁面
jumpTo('a', 'navigate', { m: 'm' }); // navigateTo到a頁面 ,路徑參數(shù)為?m=m
jumpTo('a', 'redirect', { m: 'm' }); // redirectTo到a頁面 ,路徑參數(shù)為?m=m
jumpTo(1, 'redirect', { m: 'm' }); // back 上一步 ,路徑參數(shù)為?m=m
復(fù)制代碼

項目實踐

1.native 小程序開發(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ù)器異常,請稍后再試' });
  } else {
    const { message } = e;
    Toast.show({ title: message || '服務(wù)器異常,請稍后再試' });
  }
  cb && cb();
};

const fetchData = () => {}

aync function() {
 try {
  await Loading.show();
  const { data } = await fetchData();
  this.setData({
   data
  })
  Loading.hide();
 } catch (e) {
  handleErr(e)
 }
}
復(fù)制代碼


易優(yōu)小程序(企業(yè)版)+靈活api+前后代碼開源 碼云倉庫:starfork
本文地址:http://22321a.com/wxmini/doc/course/24995.html 復(fù)制鏈接 如需定制請聯(lián)系易優(yōu)客服咨詢:800182392 點擊咨詢
QQ在線咨詢