UNPKG

@joker.front/requester

Version:

Joker 接口请求库,可通过该类库实现与@joker.server/core的快速对接。

2 lines (1 loc) 4.12 kB
function e(e,t){let r=e.indexOf(t);return r>-1&&e.splice(r,1),e}function t(){let t=[];return{add:function(r){return t.push(r),()=>{e(t,r)}},callbacks:t,reset:function(){t=[]},remove:function(r){e(t,r)}}}const r="ERROR_CODE_REQUEST_BREAK",o="ERROR_CODE_REQUEST_ABORT",a="ERROR_CODE_REQUEST",s="ERROR_CDODE_TIME_OUT",i=/^(https?:\/\/|localhost)/;let n=new Map;class l{option;beforeCallbacks=t();afterCallbacks=t();errorCallbacks=t();constructor(e){this.option=e}requestList=[];async request(t,l){let c=Object.assign({url:t,method:"POST",timeout:10,rspType:"json"},l);if(!1===i.test(c.url)&&(c.url=(this.option.base||"")+c.url),!1===await this.execBeforeEvent(c))return Promise.reject({code:r});if(c.data=await(this.option.transformReqData?.(c.data,c,this.option))??c.data,c.cache){!0===c.cache&&(c.cache={id:""});let e=`${c.url}|${c.cache?.id}`;if(c.forceRefreshCache)this.deleteCache(e);else{let t=this.getCache(e);if(void 0!==t){c.success?.(t);for(let e of this.afterCallbacks.callbacks)e(c,t);return Promise.resolve(t)}}}return new Promise(((t,r)=>{let i,f=new AbortController,h={option:c,cancel:()=>{f.abort()}},u=this.option.timeout;!1!==l?.timeout&&(u=l?.timeout),!1!==u&&u&&(i=setTimeout((()=>{f.abort();let e={code:s,message:"请求超时,请稍后重试",option:c};this.execError(e,r)}),1e3*u));let d=async(e,o)=>{let a=await(this.option.transformRspData?.(e,c,this.option))??e,s=e=>{c.cache&&(!0===c.cache&&(c.cache={id:""}),n.set(`${c.url}|${c.cache.id}`,{date:Date.now(),expiresIn:c.cache.expires,data:e})),c.success?.(e,o);for(let t of this.afterCallbacks.callbacks)t(c,e);t(e)};this.option.analyRspResult?this.option.analyRspResult(a,(e=>{s(e)}),(e=>{this.execError(Object.assign(e,{option:c}),r,o)}),o):s(a)};if(this.option.mock)this.option.mock(c).then((async e=>{await d(e,{})})).finally((()=>{e(this.requestList,h),i&&clearTimeout(i)}));else{let{body:t,headers:s}=function(e){let t={};if(e&&"object"==typeof e)for(let r in e){let o=e[r];o&&(o instanceof File||o instanceof FileList||Array.isArray(o)&&o.length&&o[0]instanceof File)&&(t[r]=o)}for(let r in t)delete e[r];if(t&&!1===function(e){if(null==e)return!0;if(function(e){return null!==e&&"object"==typeof e}(e)){for(let t in e)return!1;return!0}return!1}(t)){let r=new FormData;for(let e in t){let o=t[e];if(o instanceof FileList||Array.isArray(o))for(let t of o)r.append(e,t);else r.append(e,o)}return r.append("jsonData",JSON.stringify(e)),{body:r,headers:{}}}return{body:JSON.stringify(e),headers:{"Content-Type":"application/json"}}}(c.data);fetch(c.url,{body:t,headers:Object.assign(s,c.headers),method:c.method,signal:f.signal}).then((async e=>{if(e.ok)if("stream"===c.rspType){let t=e.body?.getReader(),o=new TextDecoder,a="";if(t)for(;;){let{done:r,value:s}=await t.read();if(r){await d(a,e);break}let i=o.decode(s);a+=i,c.stream?.(i,a)}else this.execError({code:e.status.toString(),message:"流式数据无响应",option:c},r)}else{let t=await e.json();await d(t,e)}else{let t=await e.text();this.execError({code:e.status.toString(),message:t??e.statusText,option:c},r)}})).catch((e=>{let t={code:"AbortError"===e.name?o:a,message:"AbortError"===e.name?void 0:e.message||"请求资源异常",option:c,e:e};"AbortError"!==e.name&&console.error(e),this.execError(t,r)})).finally((()=>{e(this.requestList,h),i&&clearTimeout(i)}))}this.requestList.push(h)}))}cancelAllRequest(){for(let e of this.requestList)e.cancel()}async execBeforeEvent(e){for(let t of this.beforeCallbacks.callbacks)if(!1===await t(e))return!1;return!0}deleteCache(e){n.delete(e)}getCache(e){let t=n.get(e);if(t)return t.date&&t.expiresIn&&Date.now()-t.date>t.expiresIn?void n.delete(e):t.data}execError(e,t,r){this.option.errorCodeMessage&&(e.message=this.option.errorCodeMessage[e.code]??e.message);for(let t of this.afterCallbacks.callbacks)t(e.option,e,r);for(let t of this.errorCallbacks.callbacks)t(e,r);e.option.error&&!1===e.option.error(e,r)||this.option.defaultErrorFunc&&this.option.defaultErrorFunc(e,r),t(e)}}export{s as ERROR_CDODE_TIME_OUT,o as ERROR_CODE_REQUEST_ABORT,r as ERROR_CODE_REQUEST_BREAK,a as ERROR_CODE_REQUEST_DEFAULT,l as Requester};