wxapp-http
Version:
Http module for WeChat APP
184 lines (171 loc) • 4.92 kB
text/typescript
/**
* Created by axetroy on 17-6-23.
*/
/// <reference path="./index.d.ts" />
import EventEmitter from '@axetroy/event-emitter.js';
const DEFAULT_CONFIG: HttpConfig$ = {
maxConcurrent: 10,
timeout: 0,
header: {},
dataType: 'json'
};
class Http extends EventEmitter implements Http$ {
private ctx: Wx$ = typeof wx === 'object' ? wx : { request() {} };
private queue: Entity$[] = [];
private runningTask: number = 0;
private maxConcurrent = DEFAULT_CONFIG.maxConcurrent;
private requestInterceptor: (config: HttpConfig$) => boolean = (
config: HttpConfig$
) => true;
private responseInterceptor: (
config: HttpConfig$,
response: Response$
) => boolean = (config: HttpConfig$, response: Response$) => true;
constructor(private config: HttpConfig$ = DEFAULT_CONFIG) {
super();
this.maxConcurrent = config.maxConcurrent;
}
create(config: HttpConfig$ = DEFAULT_CONFIG): Http {
return new Http(config);
}
private next(): void {
const queue: Entity$[] = this.queue;
if (!queue.length || this.runningTask >= this.maxConcurrent) return;
const entity: Entity$ = queue.shift();
const config: Config$ = entity.config;
const { requestInterceptor, responseInterceptor } = this;
if (requestInterceptor.call(this, config) !== true) {
let response: Response$ = {
data: null,
errMsg: `Request Interceptor: Request can\'t pass the Interceptor`,
statusCode: 0,
header: {}
};
entity.reject(response);
return;
}
this.emit('request', config);
this.runningTask = this.runningTask + 1;
const callBack: RequestCallBack$ = {
success: (res: Response$): void => {
entity.response = res;
this.emit('success', config, res);
responseInterceptor.call(this, config, res) !== true
? entity.reject(res)
: entity.resolve(res);
},
fail: (res: Response$): void => {
entity.response = res;
this.emit('fail', config, res);
responseInterceptor.call(this, config, res) !== true
? entity.reject(res)
: entity.resolve(res);
},
complete: (): void => {
this.emit('complete', config, entity.response);
this.next();
this.runningTask = this.runningTask - 1;
}
};
const requestConfig: RequestConfig$ = Object.assign(config, callBack);
this.ctx.request(requestConfig);
}
request(
method: string,
url: string,
data: Object | string = '',
header: HttpHeader$ = {},
dataType: string = 'json'
): Promise<Response$> {
const config: Config$ = {
method,
url,
data,
header: { ...header, ...this.config.header },
dataType: dataType || this.config.dataType
};
return new Promise((resolve, reject) => {
const entity: Entity$ = { config, resolve, reject, response: null };
this.queue.push(entity);
this.next();
});
}
head(
url: string,
data?: Object | string,
header?: HttpHeader$,
dataType?: string
): Promise<Response$> {
return this.request('HEAD', url, data, header, dataType);
}
options(
url: string,
data?: Object | string,
header?: HttpHeader$,
dataType?: string
): Promise<Response$> {
return this.request('OPTIONS', url, data, header, dataType);
}
get(
url: string,
data?: Object | string,
header?: HttpHeader$,
dataType?: string
): Promise<Response$> {
return this.request('GET', url, data, header, dataType);
}
post(
url: string,
data?: Object | string,
header?: HttpHeader$,
dataType?: string
): Promise<Response$> {
return this.request('POST', url, data, header, dataType);
}
put(
url: string,
data?: Object | string,
header?: HttpHeader$,
dataType?: string
): Promise<Response$> {
return this.request('PUT', url, data, header, dataType);
}
['delete'](
url: string,
data?: Object | string,
header?: HttpHeader$,
dataType?: string
): Promise<Response$> {
return this.request('DELETE', url, data, header, dataType);
}
trace(
url: string,
data?: Object | string,
header?: HttpHeader$,
dataType?: string
): Promise<Response$> {
return this.request('TRACE', url, data, header, dataType);
}
connect(
url: string,
data?: Object | string,
header?: HttpHeader$,
dataType?: string
): Promise<Response$> {
return this.request('CONNECT', url, data, header, dataType);
}
setRequestInterceptor(interceptor: (config: HttpConfig$) => boolean): Http {
this.requestInterceptor = interceptor;
return this;
}
setResponseInterceptor(
interceptor: (config: HttpConfig$, response: Response$) => boolean
): Http {
this.responseInterceptor = interceptor;
return this;
}
clean(): void {
this.queue = [];
}
}
export default new Http();