共计 1812 个字符,预计需要花费 5 分钟才能阅读完成。
如何基于 Promise 设计简略的申请 / 响应拦截器
面试官问你,如何能力设计出像 Axios 这样牛皮的申请和响应拦截器? 能不能简略手写其中的原理
// xhr 适配器 | |
var dispatch = (config) => {return new Promise((resolve, reject) => {setTimeout(() => { | |
// 模仿 xhr 后果响应值 | |
resolve('cpp', config); | |
}, 1000); | |
}); | |
}; | |
// 申请 | |
function request(config) { | |
var promise; | |
var interceptor = { | |
request: [(config) => {console.log(config, 'request config'); | |
return config; | |
}, | |
(err) => {console.log(err); | |
}, | |
], | |
response: [(res) => {console.log(res, 'response res'); | |
return res; | |
}, | |
(err) => {console.log(err); | |
}, | |
], | |
}; | |
var chain = [dispatch, null]; | |
chain.unshift(...interceptor.request); | |
// 留神 chain 数组的前后程序 | |
chain = chain.concat(interceptor.response); | |
promise = Promise.resolve(config); | |
while (chain.length) {promise = promise.then(chain.shift(), chain.shift()); | |
} | |
return promise; | |
} | |
request({ | |
name: 'CPP REQUEST', | |
url: 'api/get/data', | |
}).then((res) => {console.log(res, 'LAST RES'); | |
}); | |
// 打印后果 | |
// request config | |
// response res | |
// cpp LAST RES |
之前始终不是特地能了解拦截器的外围实现原理,也就是上面这几段代码
while (chain.length) {promise = promise.then(chain.shift(), chain.shift()); | |
} | |
return promise |
忽然某一个时刻想通了,其实这也是奇妙利用了 Promise 外围异步链式调用,把下面几行代码改成这样预计都能了解了
var dispatch = (config) => {return new Promise((resolve, reject) => {setTimeout(() => {resolve('cpp', config); | |
}, 1000); | |
}); | |
}; | |
function request(config) { | |
var promise; | |
var interceptor = { | |
request: [(config) => {console.log(config, 'request config'); | |
return config; | |
}, | |
(err) => {console.log(err); | |
}, | |
], | |
response: [(res) => {console.log(res, 'response res'); | |
return res; | |
}, | |
(err) => {console.log(err); | |
}, | |
], | |
}; | |
var chain = [dispatch, null]; | |
chain.unshift(...interceptor.request); | |
chain = chain.concat(interceptor.response); | |
promise = Promise.resolve(config); | |
// while (chain.length) {// promise = promise.then(chain.shift(), chain.shift()); | |
// } | |
return promise.then(chain.shift(), chain.shift()).then(chain.shift(), chain.shift()).then(chain.shift(), chain.shift());; | |
} | |
request({ | |
name: 'CPP REQUEST', | |
url: '/api/data', | |
}).then((res) => {console.log(res, 'LAST RES'); | |
}); | |
// 打印后果 | |
// request config | |
// response res | |
// cpp LAST RES |
正文完