axios 차단기의 실현
차단기 설계와 실현
# 요구 사항 분석
우리는 요청의 발송과 응답을 차단할 수 있기를 희망한다. 즉, 요청을 보내기 전과 응답을 받은 후에 추가 논리를 할 수 있기를 바란다.
우리가 설계하고자 하는 차단기의 사용 방식은 다음과 같다.
//
axios.interceptors.request.use(function (config) { // return config; }, function (error) { // return Promise.reject(error); }); // axios.interceptors.response.use(function (response) { // return response; }, function (error) { // return Promise.reject(error); });
axios
대상에 하나의 interceptors
대상 속성이 있는데 이 속성은 request
와 response
두 개의 속성이 있는데 모두 하나의 use
방법이 있고 use
방법은 2개의 파라미터를 지원하며 첫 번째 파라미터는 Promise의 resolve
함수와 유사하고 두 번째 파라미터는 Promise의 reject
함수와 유사하다.우리는 resolve
함수와 reject
함수에서 동기화 코드나 비동기 코드 논리를 실행할 수 있다.그리고 우리는 여러 개의 차단기를 추가할 수 있습니다. 차단기의 실행 순서는 체인식으로 순서대로 실행하는 방식입니다.
request
차단기에 대해 다음에 추가된 차단기는 요청 전 과정에서 먼저 실행됩니다.response
차단기에 대해 먼저 추가된 차단기는 응답 후에 실행됩니다.axios.interceptors.request.use(config => { config.headers.test += '1' return config }) axios.interceptors.request.use(config => { config.headers.test += '2' return config })
또한 다음과 같은 차단기를 삭제할 수도 있습니다.
const myInterceptor = axios.interceptors.request.use(function () {/*...*/}) axios.interceptors.request.eject(myInterceptor)
# 전체적인 디자인
우리는 먼저 한 장의 그림으로 차단기 작업 절차를 보여 준다.
전체 과정은 체인식 호출 방식이고 모든 차단기는 동기화와 비동기 처리를 지원할 수 있기 때문에 우리는 자연스럽게Promise 체인을 사용하는 방식으로 전체 호출 과정을 실현하는 것을 연상한다.
이 Promise 체인의 실행 과정에서 요청 차단기
resolve
함수 처리는 config
대상이고, 해당 차단기resolve
함수 처리는 response
대상이다.차단기의 작업 흐름을 이해한 후에, 우리는 삭제와 반복 차단기를 추가할 수 있도록 차단기 관리 클래스를 만들어야 합니다.
# 차단기 관리 클래스 구현
수요에 따라
axios
대상속성이 하나 있고 이 속성은 interceptors
과request
2개의 속성이 있다. 그들은 대외적으로 response
방법을 제공하여 차단기를 추가한다. 우리는 이 두 속성을 차단기 관리 대상으로 볼 수 있다.use
방법은 2개의 매개 변수를 지원한다. 첫 번째는 use
함수, 두 번째는 resolve
함수이다. reject
함수의 매개 변수에 대해 요청 차단기는 resolve
유형이고 응답 차단기는 AxiosRequestConfig
유형이다.AxiosResponse
함수의 매개 변수 유형은 reject
유형이다.상술한 분석에 근거하여 우리는 먼저 차단기 관리 대상의 대외 인터페이스를 정의한다.
# 인터페이스 정의
any
: export interface AxiosInterceptorManager<T> { use(resolved: ResolvedFn<T>, rejected?: RejectedFn): number eject(id: number): void } export interface ResolvedFn<T=any> { (val: T): T | Promise<T> } export interface RejectedFn { (error: any): any }
여기에서 우리는
types/index.ts
범용 인터페이스를 정의했다. 왜냐하면 AxiosInterceptorManager
함수의 매개 변수에 대해 요청 차단기와 응답 차단기는 다르기 때문이다.# 코드 구현
import { ResolvedFn, RejectedFn } from '../types' interface Interceptor<T> { resolved: ResolvedFn<T> rejected?: RejectedFn } export default class InterceptorManager<T> { private interceptors: Array<T> | null> constructor() { this.interceptors = [] } use(resolved: ResolvedFn<T>, rejected?: RejectedFn): number { this.interceptors.push({ resolved, rejected }) return this.interceptors.length - 1 } forEach(fn: (interceptor: Interceptor<T>) => void): void { this.interceptors.forEach(interceptor => { if (interceptor !== null) { fn(interceptor) } }) } eject(id: number): void { if (this.interceptors[id]) { this.interceptors[id] = null } } }
우리는
resolve
범용 클래스를 정의했고 내부적으로 개인 속성InterceptorManager
을 유지했다. 이것은 차단기를 저장하는 데 사용되는 수조이다.이 종류는 대외적으로 세 가지 방법을 제공했는데 그 중에서 interceptors
인터페이스는 차단기를 use
에 추가하고 삭제할 수 있도록 되돌려주는 것이다.interceptors
인터페이스는 역력id
에 사용되는 것으로 하나의 함수를 지원하며 역력 과정에서 이 함수를 호출하고 각각forEach
을 이 함수의 매개 변수로 전입한다.interceptors
는 차단기를 삭제하고 차단기를 전송한 interceptor
을 통해 삭제한다.# 체인 호출 구현
이 소절은 Promise에 대한 파악과 이해가 필요합니다. mdn에 가서 공부할 수 있습니다.
차단기 관리 클래스를 실현하면
eject
에서 id
속성을 정의합니다. 그 유형은 다음과 같습니다.interface Interceptors {
request: InterceptorManager> response: InterceptorManager> } export default class Axios { interceptors: Interceptors constructor() { this.interceptors = { request: new InterceptorManager>(), response: new InterceptorManager>() } } }
Axios
유형은 2개의 속성을 가지고 하나는 요청 차단기 관리 클래스의 실례이고 하나는 응답 차단기 관리 클래스의 실례이다.우리가 실례화interceptors
류를 할 때, 그 구조기에서 이 Interceptors
실례 속성을 초기화합니다.다음은
Axios
방법의 논리를 수정하고 차단기 체인 호출의 논리를 추가합니다.interceptors
: interface PromiseChain {
resolved: ResolvedFn | ((config: AxiosRequestConfig) => AxiosPromise) rejected?: RejectedFn } request(url: any, config?: any): AxiosPromise { if (typeof url === 'string') { if (!config) { config = {} } config.url = url } else { config = url } const chain: PromiseChain[] = [{ resolved: dispatchRequest, rejected: undefined }] this.interceptors.request.forEach(interceptor => { chain.unshift(interceptor) }) this.interceptors.response.forEach(interceptor => { chain.push(interceptor) }) let promise = Promise.resolve(config) while (chain.length) { const { resolved, rejected } = chain.shift()! promise = promise.then(resolved, rejected) } return promise }
먼저
request
유형의 수조core/Axios.ts
를 구성하고 PromiseChain
함수를 chain
속성에 부여한다.이어서 요청 차단기를 dispatchRequest
앞에 삽입합니다.그리고 응답 차단기를 반복해서 resolved
뒤에 삽입합니다.다음은 이미resolve
chain
를 정의하고 이것chain
을 순환하여 모든 차단기 대상을 가져와 그것들promise
함수와 chain
함수를 resolved
매개 변수에 추가하면 Promise의 체인 호출 방식을 통해 차단기의 층층이 체인 호출 효과를 실현하는 것과 같다.우리 차단기의 실행 순서를 주의하십시오. 요청 차단기는 먼저 실행한 후에 추가한 다음에 먼저 추가한 것을 실행합니다.응답 차단기에 대해서는 먼저 추가한 것을 실행하고 나중에 추가한 것을 실행합니다.
#demo 작성
rejected
디렉터리에서 promise.then
디렉터리를 만들고, examples
디렉터리에서 interceptor
디렉터리를 만듭니다.
lang="en"> > charset="utf-8"> >Interceptor example<span class="token tag"><span class="token tag"><span class="token punctuation"/></span></span> > > > src<span class="token attr-value"><span class="token punctuation">=<span class="token punctuation">"/__build__/interceptor.js<span class="token punctuation">"<span class="token punctuation">><span class="token script language-javascript"><span class="token tag"><span class="token tag"><span class="token punctuation"> > > >
다음으로
interceptor
를 포털 파일로 만듭니다.import axios from '../../src/index'
axios.interceptors.request.use(config => { config.headers.test += '1' return config }) axios.interceptors.request.use(config => { config.headers.test += '2' return config }) axios.interceptors.request.use(config => { config.headers.test += '3' return config }) axios.interceptors.response.use(res => { res.data += '1' return res }) let interceptor = axios.interceptors.response.use(res => { res.data += '2' return res }) axios.interceptors.response.use(res => { res.data += '3' return res }) axios.interceptors.response.eject(interceptor) axios({ url: '/interceptor/get', method: 'get', headers: { test: '' } }).then((res) => { console.log(res.data) })
이 데모는 요청 차단기 3개를 추가했습니다. 응답 차단기 3개를 추가하고 두 번째를 삭제했습니다.이 데모를 실행하면 브라우저를 통해 접근합니다. 저희가 보낸 요청에
index.html
요청 헤더를 추가했습니다. 그 값은 app.ts
입니다.우리의 응답 데이터는 test
, 응답 차단기의 처리를 거쳐 최종적으로 우리가 출력한 데이터는 321
이다.이로써 우리는
hello
차단기 기능을 실현했다. 이것은 매우 실용적인 기능으로 실제 업무에서 우리는 그것을 이용하여 로그인 권한 인증과 같은 수요를 만들 수 있다.우리는 현재
hello13
요청을 보내면 종종 한 무더기의 설정이 전송되지만, 우리도 ts-axios
자체에도 일부 기본 설정이 있기를 바란다. 우리는 사용자가 전송한 사용자 정의 설정과 기본 설정을 한 겹으로 통합하기를 바란다.사실 대부분의 JS 라이브러리는 비슷한 방법입니다.다음 장에서 우리는 이 기능을 실현할 것이다.다음으로 전송:https://www.cnblogs.com/QianDingwei/p/11403923.html
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.