UNPKG

ryoko

Version:

a requestion lib based on the fetch native api

76 lines (75 loc) 3.05 kB
import { extend, override, } from '../shared/utils'; import Interceptor from './interceptor'; import defaultRyokoConfig from '../helpers/defaults'; import dispatchFetch from './dispatchFetch'; import { ryokoMethods } from '../helpers/constant'; import mergeRyokoConfig from '../helpers/mergeConfig'; // a request method based on the native fetch api export default class Ryoko { constructor(config) { this.defaults = extend({}, config, defaultRyokoConfig); this.interceptors = { request: new Interceptor(), response: new Interceptor(), }; } request(config) { const mergedConfig = mergeRyokoConfig(this.defaults, config); const promisesQueueBefore = [], promisesQueueAfter = []; this.interceptors.request.traverse((interceptor) => { promisesQueueBefore.push(interceptor.success, interceptor.failure); }); this.interceptors.response.traverse((interceptor) => { promisesQueueAfter.push(interceptor.success, interceptor.failure); }); let synchronous = true; if (!synchronous) { let prePromise = Promise.resolve(mergedConfig); while (promisesQueueBefore.length) { prePromise = prePromise.then(promisesQueueBefore.shift(), promisesQueueBefore.shift()); } const corePromise = prePromise.then(dispatchFetch.bind(this), void 0); let endPromise = corePromise; while (promisesQueueAfter.length) { endPromise = endPromise.then(promisesQueueAfter.shift(), promisesQueueAfter.shift()); } ; return endPromise; } let actualMergedConfig = mergedConfig; let syncEndPromise; while (promisesQueueBefore.length) { const requestInterceptor = promisesQueueBefore.shift(); const responseInterceptor = promisesQueueBefore.shift(); try { actualMergedConfig = requestInterceptor(mergedConfig); } catch (err) { responseInterceptor(err); break; } } try { syncEndPromise = dispatchFetch.call(this, actualMergedConfig); } catch (err) { return Promise.reject(err); } while (promisesQueueAfter.length) { syncEndPromise = syncEndPromise.then(promisesQueueAfter.shift(), promisesQueueAfter.shift()); } return syncEndPromise; } } //默认class定义的类的原型方法不能枚举 Object.defineProperty(Ryoko.prototype, 'request', { enumerable: true, }); ryokoMethods.forEach((method, i) => { Reflect.set(Ryoko.prototype, method, function (url, config) { const endConfig = override({}, config, { method, url, }); return (typeof this === 'function' ? this(endConfig) : this.request.call(this, endConfig)); }); });