Recently, I want to use the full js system to write a front-end and back-end learning, and created a set of TODOList project trainers. Currently only the back-end demo has been written, and the front-end is using vue. And prepare to write it again later with react and flutter.
This project
Backend demo
premise
Framework 7, a mobile ui framework, was used when writing the practitioner project, because the animation of the framework was so good that it was chosen. But in the process of using the framework, we found that the ajax request library is very simple, so we manually encapsulated it with reference to axios to support promise and interceptor.
Hands on
Don't talk too much nonsense. Code it.
comover.js
import { Request as F7Request } from "framework7"; // Encapsulating the original request object as a Promise object function adapter(config) { return new Promise(function(resolve, reject) { F7Request({ url: `${config.baseUrl}${config.url}`, method: config.method, headers: config.headers, data: config.data, success(data, status, xhr) { resolve({ data: JSON.parse(data), status: status, config: config, xhr: xhr }); }, error(xhr, status) { let error = new Error( `Request failed with status code ${status}` ); error.xhr = xhr; reject(error); } }); }); } // Send requests function dispatchRequest(config) { return adapter(config).then( function onAdapterResolution(response) { return response; }, function onAdapterRejection(reason) { return Promise.reject(reason); } ); } export default class Comeover { interceptors = {}; requestHandlers = []; responseHandlers = []; config = {}; constructor(config = ({ baseUrl = "" } = {})) { const self = this; this.config = { ...config }; this.interceptors = { request: { use(fulfilled, rejected) { self.requestHandlers.push({ fulfilled, rejected }); } }, response: { use(fulfilled, rejected) { self.responseHandlers.push({ fulfilled, rejected }); } } }; // Method runtime binding context in class in ES6 this.request = this.request.bind(this); } request(config) { // Merge default config with config when sending requests let inconfig = { ...this.config, ...config }; // Create Promise Chain let chain = [dispatchRequest, undefined]; // Create promise objects passed in the initial Promise chain let promise = Promise.resolve(inconfig); // Injecting the interceptor into the Promise chain this.requestHandlers.forEach(interceptor => { chain.unshift(interceptor.fulfilled, interceptor.rejected); }); this.responseHandlers.forEach(interceptor => { chain.push(interceptor.fulfilled, interceptor.rejected); }); // Running Promise Chain while (chain.length) { promise = promise.then(chain.shift(), chain.shift()); } // Returns the final promise object return promise; } }
Use
This example uses nprograms to pretend to show the progress of the request before and after all requests
import Comeover from "./comeover"; import Np from "nprogress"; const baseUrl = process.env.NODE_ENV === "development" ? "" : /* Upline address */ ""; const comeover = new Comeover({ baseUrl }); comeover.interceptors.request.use( config => { Np.start(); return config; }, error => { Np.done(); return Promise.reject(error); } ); comeover.interceptors.response.use( response => { Np.done(); return response; }, error => { Np.done(); return Promise.reject(error); } ); export { request };
Request
comeover.request({ url: "/api/login", method: "post", data: { email: this.email, password: this.password } }) .then(({ data }) => { this.$store.commit("login", { token: data.message }); router.back(); }) .catch(err => { app.dialog.alert("ERROR Incorrect username or password", "Landing Failure"); });
summary
You can also refer to axios to continue encapsulating separate get, post, and so on, so that the demo is not written.
The Promise chain is an array, and then puts the request interceptor in front of the real request and the responding interceptor behind the real request. Then, in the order of resolve before reject after reject, paired loops are injected into promise.then. The real request resove and reject are written in the dispatchRequest, so there is no reject in the dispatchRequest, so we need to add an undefined.
When ES6's instantiation method is used alone, this pointing will be problematic and needs to be addressed. individualization