wx.request 经 Promise 封装后,如何拿到requestTask
大家会用 promise 将 wx.request 包装一层。但经过这么一层包装后,就拿到不到 requestTask,从而调用不了 abort 方法。大家都是如何解决的?
代码来自:https://www.kancloud.cn/xiaoyulive/wechat/526990
class Request { constructor (parms) { this .withBaseURL = parms.withBaseURL this .baseURL = parms.baseURL } get (url, data) { return this .request( 'GET' , url, data) } post (url, data) { return this .request( 'POST' , url, data) } put (url, data) { return this .request( 'PUT' , url, data) } request (method, url, data) { const vm = this return new Promise((resolve, reject) => { wx.request({ url: vm.withBaseURL ? vm.baseURL + url : url, data, method, success (res) { resolve(res) }, fail () { reject({ msg: '请求失败' , url: vm.withBaseURL ? vm.baseURL + url : url, method, data }) } }) }) } } const request = new Request({ baseURL: 'http://test' , withBaseURL: true }) module.exports = request |
3 回复
ts源码:
export namespace Hz.Http { const ES6Promise = require( 'es6-promise' ); export interface DatasObject { [data: string]: number | string | string[] | undefined; } export interface HeadersObject { [header: string]: number | string | string[] | undefined; } export interface RequestParams { url: string; method?: string; dataType?: string; data?: string | DatasObject | ArrayBuffer; header?: HeadersObject; responseType?: string; } export class HttpError extends Error { public statusCode: number; public header: HeadersObject; public body: string | object | ArrayBuffer; constructor(statusCode: number, header: HeadersObject, body: string | object | ArrayBuffer) { super (`response status code: ${statusCode}`); this .statusCode = statusCode; this .header = header; this .body = body; } } export class ResponsePromise<T> extends ES6Promise<T> { public statusCode: number; public header: HeadersObject; public body: string | object | ArrayBuffer; public requestTask: WechatMiniprogram.RequestTask; constructor(executor: (resolve: (value?: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void) { super (executor); } public onHeadersReceived(callback: WechatMiniprogram.RequestTaskOnHeadersReceivedCallback) { this .requestTask.onHeadersReceived(callback); } public offHeadersReceived(callback: WechatMiniprogram.RequestTaskOffHeadersReceivedCallback) { this .requestTask.offHeadersReceived(callback); } public abort(): void { this .requestTask.abort(); } } export class Request { public static ExecAsync<T>(pars: RequestParams): ResponsePromise<T> { var requestTask: WechatMiniprogram.RequestTask; var p = new ResponsePromise<T>((resolve, reject) => { try { requestTask = wx.request({ url: pars.url, data: pars.data, header: pars.header, method: pars.method, dataType: pars.dataType, responseType: pars.responseType, success(res) { if (res.statusCode >= 200 && res.statusCode < 300) { p.statusCode = res.statusCode; p.header = res.header; p.body = res.data; resolve(res.data); } else { reject( new HttpError(res.statusCode, res.header, res.data)); } }, fail(err) { reject( new Error(err.errMsg)); } }); } catch (e) { reject(e); } }); p.requestTask = requestTask; return p; } public static getAsync<T>(url: string, data?: string | DatasObject | ArrayBuffer, header?: HeadersObject): ResponsePromise<T> { return Request.ExecAsync<T>({ url: url, data: data, header: header, method: "GET" }); } public static postAsync<T>(url: string, data?: string | DatasObject | ArrayBuffer, header?: HeadersObject): ResponsePromise<T> { return Request.ExecAsync<T>({ url: url, data: data, header: header, method: "POST" }); } public static deleteAsync<T>(url: string, data?: string | DatasObject | ArrayBuffer, header?: HeadersObject): ResponsePromise<T> { return Request.ExecAsync<T>({ url: url, data: data, header: header, method: "DELETE" }); } } } |
class Request {
constructor(parms) {
this.withBaseURL = parms.withBaseURL;
this.baseURL = parms.baseURL;
this.requestTask = null;
}
get(url, data) {
return this.request('GET', url, data);
}
post(url, data) {
return this.request('POST', url, data);
}
put(url, data) {
return this.request('PUT', url, data);
}
request(method, url, data) {
const vm = this;
return new Promise((resolve, reject) => {
this.requestTask = wx.request({
url: vm.withBaseURL ? vm.baseURL + url : url,
data,
method,
success(res) {
resolve(res);
},
fail() {
reject({
msg: '请求失败',
url: vm.withBaseURL ? vm.baseURL + url : url,
method,
data
});
}
});
});
}
abort() {
if (this.requestTask) {
this.requestTask.abort();
}
}
}
const request = new Request({
baseURL: 'http://test',
withBaseURL: true
});
module.exports = request;
调用:
request.get(xxx, xxx).then((res) => {
request.abort();
})
let task = {} const promise = new Promise((resolve) => { let timer task.abort = function () { clearTimeout(timer) } timer = setTimeout(() => { resolve() }, 1000) }) promise.task = task return promise } function a() { return r() } var promise = a() promise.then(res => { console.log(1) }) promise.task.abort() a().then(res => { console.log(2) }) |
demo实现思路,挂载在返回的promise上,但会有问题,你可以看到在调用的时候需要手动声明一个promise变量,不能直接a().then() 因为then返回的是一个新的Promise,上面没有挂载的task。
今天遇到了这个问题,在不影响从前的代码的情况下想出来的。更好的思路暂时没有。这里就抛砖引玉了