tsp-component
Version:
提供多端和react版本的UI组件
201 lines (195 loc) • 6.04 kB
text/typescript
import assign from 'object-assign';
import ajax from './index';
import Cache from './cache';
class WebApi {
constructor(ajaxUrl: string, dbParams: TspComponentAjaxCacheParams) {
this.ajaxUrl = ajaxUrl;
try {
if ('open' in indexedDB) {
this.isSupportIndexDB = true;
}
} catch (e) {
this.isSupportIndexDB = false;
}
if (this.isSupportIndexDB && dbParams && dbParams.dbName && dbParams.tableName) {
this.cache = new Cache(dbParams.dbName, dbParams.tableName);
this.cache.open();
}
}
/**
* 成功后执行的响应函数
*/
public static response: (result: any, callback: (params: any) => void, sendData: any) => void;
/**
* 响应成功后无论执行码是什么都要执行的函数
*/
public static alwaysDone: () => void;
/**
* 默认请求参数
*/
public static defaultParams: any;
/**
* 代理
*/
public static proxy: string;
/**
* 已发送的请求
*/
public static requested: XMLHttpRequest[] = [];
/**
* 取消请求
*/
public static abort(noAbortUrl?: string[], abortUrl?: string[]): void {
const length = WebApi.requested.length;
const noAbortUrlLength = noAbortUrl ? noAbortUrl.length : 0;
const abortUrlLength = abortUrl ? abortUrl.length : 0;
let i;
let j;
if (abortUrlLength) {
for (i = 0; i < length; i++) {
if (WebApi.requested[i].readyState === 1) {
for (j = 0; j < abortUrlLength; j++) {
if (WebApi.requested[i]['url'] === abortUrl[j]) {
WebApi.requested[i]['isAbort'] = true;
WebApi.requested[i].abort();
break;
}
}
}
}
} else {
for (i = 0; i < length; i++) {
let flag = true;
if (WebApi.requested[i].readyState === 1) {
for (j = 0; j < noAbortUrlLength; j++) {
if (WebApi.requested[i]['url'] !== noAbortUrl[j]) {
flag = false;
break;
}
}
if (flag) {
WebApi.requested[i]['isAbort'] = true;
WebApi.requested[i].abort();
}
}
}
}
}
/**
* 判断是否支持indexedDB
*/
private isSupportIndexDB: boolean;
/**
* api请求基本地址
*/
private ajaxUrl: string;
/**
* Cache 实例
*/
private cache: Cache;
/**
* post请求
*/
public post(options: TspComponentAjaxPostOption): void {
// ajax需要的url
let apiUrl;
// request对象,用于执行abort
let requested;
// 从数据库读取的数据
let cacheResult;
// 判断api是否带有http
if (options.api.indexOf('://') >= 0) {
apiUrl = options.api;
} else {
apiUrl = WebApi.proxy ? WebApi.proxy + options.api : this.ajaxUrl + options.api;
}
const sendData = WebApi.defaultParams ? assign({}, WebApi.defaultParams, options.params) : options.params;
const xhrType = options.type ? options.type : 'POST';
const apiInfo = {
api: apiUrl,
type: xhrType,
params: sendData
};
const ajaxSendObj = {
url: apiUrl,
type: xhrType,
contentType: options.contentType,
customHeader: options.customHeader,
timeout: options.timeout,
data: sendData,
success: (result, xhr) => {
if (WebApi.response) {
WebApi.response(result, (status) => {
if (options.isCache && this.isSupportIndexDB) {
if ((JSON.stringify(cacheResult.value) !== JSON.stringify(result)) && status) {
const value = {
api: JSON.stringify({ url: apiUrl, params: options.params }),
value: result
};
const cacheUpdate = cacheResult.value ? true : false;
options.success(result, status, cacheUpdate);
if (cacheResult.value) {
this.cache.put(value);
// Toast.text('内容已更新');
} else {
this.cache.add(value);
}
} else if (!cacheResult.value) {
options.success(result, status);
}
} else {
options.success(result, status);
}
}, JSON.stringify(assign({}, apiInfo, { result })));
} else {
console.error('缺少WebApi.response');
}
if (WebApi.alwaysDone) {
WebApi.alwaysDone();
}
},
error: (xhr) => {
if (xhr['isAbort']) {
return;
}
if (WebApi.alwaysDone) {
WebApi.alwaysDone();
}
if (options.isCache && this.isSupportIndexDB) {
if (options.timeoutCallback && !cacheResult.value) {
options.timeoutCallback(xhr);
}
} else if (options.timeoutCallback) {
options.timeoutCallback(xhr);
}
},
complete(xhr: XMLHttpRequest): void {
if (options.complete) {
options.complete(xhr);
}
}
};
if (options.isCache && this.isSupportIndexDB) {
this.cache.read({
key: JSON.stringify({ url: apiUrl, params: options.params }),
onsuccess(result: any): void {
cacheResult = result;
requested = ajax(ajaxSendObj);
if (options.cacheReadSuccess) {
options.cacheReadSuccess(result.value);
}
if (result.value) {
WebApi.response(result.value, (params) => {
options.success(result.value, params, false);
}, JSON.stringify(assign({}, apiInfo, { result })));
}
WebApi.requested.push(requested);
}
});
} else {
requested = ajax(ajaxSendObj);
WebApi.requested.push(requested);
}
}
}
export default WebApi;