fetch.js
const api = 'www.qq.com'
export const Fetch = ({
url = '',
data = {},
header = { "content-type": "application/json" },
method = 'GET',
api = Api
}) => {
return new Promise((resolve, reject) => {
wx.request({
url: api + url,
header: header,
method: method,
data: data,
success: res => {
// 成功时的处理
if (res.data.error == 0) {
resolve(res.data);
} else {
reject(res.data);
}
},
fail: err => {
reject(err);
}
})
})
}
api.js
import { Fetch } from './fetch.js';
export const PostMiniList = data => {
return Fetch({
url: '/post/post_mini_list.json',
data: data,
method: 'POST',
header: {
'content-type': 'application/x-www-form-urlencoded'
}
})
}
export const GetMiniList = data => {
return Fetch({
url: '/get/get_mini_list.json',
data: data
})
}
index.js
import { PostMiniList, GetMiniList } from './api.js';
PostMiniList({
a:1,
b:2
}).then(
res => {
// 成功处理
},
err => {
// 失败处理
}
)
GetMiniList({
a:1,
b:2
}).then(
res => {
// 成功处理
},
err => {
// 失败处理
}
)
把所有api放在api.js里统一管理,利用promise使我们只关注返回的结果
将api转换为返回promise对象(引用自https://github.com/youngjuning/wxPromise)
//将转换为Promise对象的api挂载在该对象下
wx.pro = {}
//微信api请求失败标识
const WX_FAIL = Symbol(
'微信API请求失败'
);
/**
* 将函数变成Promise对象,并添加finally,意为无论success还是fail都会执行的操作
* fail默认返回码为wx_fail,方便catch捕获后明确错误原因
*/
const promisify = (api) => {
return
(options, ...params) => {
return
new
Promise((resolve, reject) => {
api(Object.assign({}, options, {
success: resolve,
fail: (err) => {
reject({
code: WX_FAIL,
msg: err
})
}
}), ...params)
Promise.prototype.finally =
function
(callback) {
let P =
this
.constructor
return
this
.then(
value => P.resolve(callback()).then(() => value),
reason => P.resolve(callback()).then(() => {
throw
reason })
)
}
})
}
}
/**
* 将Promise化的api挂在在wx.pro对象下,你仍然可以使用wx.api调用源生api
* 注:对于同步操作,wx.pro.api 与 wx.api 相同
* 同步操作包括:(即没有success、fail和complete属性的api)
* 1、...Sync【√】
* 2、on...【√】
* 3、create... 除了 createBLEConnection【√】
* 4、...Manager【√】
* 5、pause...【√】
* 6、stopRecord、stopVoice、stopBackgroundAudio、stopPullDownRefresh【√】
* 7、hideKeyboard、hideToast、hideLoading、showNavigationBarLoading、hideNavigationBarLoading【√】
* 8、canIUse、navigateBack、closeSocket、pageScrollTo、drawCanvas【√】
*/
const wxPromise = () => {
// 将 promise 方法 挂载到 wx.pro 对象上
for
(let key
in
wx) {
if
(wx.hasOwnProperty(key)) {
if
(/^on|^create|Sync$|Manager$|^pause/.test(key) && key !==
'createBLEConnection'
|| key ===
'stopRecord'
|| key ===
'stopVoice'
|| key ===
'stopBackgroundAudio'
|| key ===
'stopPullDownRefresh'
|| key ===
'hideKeyboard'
|| key ===
'hideToast'
|| key ===
'hideLoading'
|| key ===
'showNavigationBarLoading'
|| key ===
'hideNavigationBarLoading'
|| key ===
'canIUse'
|| key ===
'navigateBack'
|| key ===
'closeSocket'
|| key ===
'closeSocket'
|| key ===
'pageScrollTo'
|| key ===
'drawCanvas'
) {
wx.pro[key] = wx[key]
}
else
{
wx.pro[key] = promisify(wx[key])
}
}
}
}
wxPromise();
封装请求
const post =
function
(url, params, {
encode =
true
,
duration,
timeout = 30000,
isShow =
true
} = {}) {
if
(isShow) {
wx.showLoading({
title:
'请等待...'
,
icon:
'loading'
,
mask:
true
});
}
const clock = timerTask(timeout);
return
Promise.race([wx.pro.request({
url: config.reqSite +
'api/'
+ url,
data: assembleRequestData(params, encode),
header: getReqHeader(),
method:
'POST'
}), clock.timer]).then(res => {
clearTimeout(clock.id);
//处理响应体
return
handleResponse(res);
}).then(res => {
if
(isShow) {
wx.hideLoading();
}
//判断业务状态是否为成功
if
(res.data.RetStatus ==
'S'
) {
//设置本地cookie
setLocalCookie(res);
return
res.data.RetData;
}
else
{
//业务状态为失败时,默认弹出提示信息
myToast(res.data.RetMsg, duration);
return
Promise.reject(res);
}
}).
catch
(err => {
//微信请求失败时调用
if
(err.code == WX_FAIL) {
if
(isShow) {
wx.hideLoading();
}
myToast(MSG_NONETWORK);
}
return
Promise.reject(err);
}).finally(() => {
clearTimeout(clock.id);
})
}
学了阮一峰的es6后一直想用Promise 封装下request,有现成的就不用这么麻烦了
request:
function
(object) {
//检查token
if
(!object.isNoNeedLogin && !
this
.checkToken()) {
wx.showToast({
title:
"请重新登录"
,
icon:
"none"
})
wx.clearStorageSync();
setTimeout(
function
() {
wx.redirectTo({
url:
'/pages/user/login'
,
})
}, 500)
return
false
;
}
wx.showNavigationBarLoading();
wx.request({
url:
this
.siteInfo.apiBaseUrl + object.url,
header: object.header || {
'token'
:
this
.getToken()
},
data: object.data || {},
method: object.method ||
"GET"
,
dataType: object.dataType ||
"json"
,
success:
function
(res) {
if
(object.success) {
object.success(res);
}
if
(res.data.code == 1001) {
wx.showToast({
title: res.data.msg,
icon:
"none"
})
wx.clearStorageSync();
setTimeout(
function
() {
wx.redirectTo({
url:
'/pages/user/login'
,
})
}, 500)
return
false
;
}
else
if
(res.data.code > 0) {
}
else
{
wx.showToast({
title: res.data.msg ? res.data.msg :
"系统繁忙,请稍后再试"
,
icon:
"none"
,
duration: 2000
})
}
},
fail:
function
(res) {
//wx.hideLoading();
console.warn(
'--- request fail >>>'
);
console.warn(res);
console.warn(
'<<< request fail ---'
);
wx.showToast({
title:
"网络请求出错,请检查网络设置,错误码:"
.res.statusCode,
icon:
"none"
})
// wx.showModal({
// title: "网络请求出错",
// content: "网络请求出错,请检查网络设置",
// showCancel: false,
// success: function (res) {
// if (object.fail) {
// object.fail(res);
// }
// }
// });
},
complete:
function
(res) {
if
(res.statusCode != 200) {
console.log(
'--- request http error >>>'
);
console.log(res.statusCode);
console.log(res.data);
console.log(
'<<< request http error ---'
);
}
if
(object.complete) {
object.complete(res);
}
wx.hideNavigationBarLoading();
}
});
}
拿走不谢,不用那么麻烦
你写的很不错,但是并不适用于所有人,很多需求其实是在请求接口的页面去处理结果,你满足不了这种需求,除非用object里添加回调函数,但是那样更麻烦
或者说,你的意思是每个页面都放一个request方法?那你的api怎么统一管理?代码有多冗余?
封装到APP.JS里面,需要什么回调函数就自己添加了,我这边状态码不多,足够用了,原生的wx.request 一样的用法。常见的几种状态 异常,失败,成功,未登录几个常规的都有处理。增强了原生wx.request 的用法
兄弟,还是你的接口太少,等你的项目涉及到几十几百个接口的时候,你就知道对接口进行统一管理有多重要了