æ£å¦æä»¬æç¥éçï¼fetch è¿åä¸ä¸ª promiseãJavaScript é常并没æâ䏿¢â promise çæ¦å¿µãé£ä¹æä»¬ææ ·æè½åæ¶ä¸ä¸ªæ£å¨æ§è¡ç fetch å¢ï¼ä¾å¦ï¼å¦æç¨æ·å¨æä»¬ç½ç«ä¸çæä½è¡¨æä¸åéè¦æä¸ªæ§è¡ä¸ç fetchã
ä¸ºæ¤æä¸ä¸ªç¹æ®çå
建对象ï¼AbortControllerãå®ä¸ä»
å¯ä»¥ä¸æ¢ fetchï¼è¿å¯ä»¥ä¸æ¢å
¶ä»å¼æ¥ä»»å¡ã
ç¨æ³é常ç®åã
AbortController 对象
å建ä¸ä¸ªæ§å¶å¨ï¼controllerï¼ï¼
let controller = new AbortController();
æ§å¶å¨æ¯ä¸ä¸ªæå ¶ç®åç对象ã
- å®å
·æåä¸ªæ¹æ³
abort()ï¼ - ååä¸ªå±æ§
signalï¼æä»¬å¯ä»¥å¨è¿ä¸ªå±æ§ä¸è®¾ç½®äºä»¶çå¬å¨ã
å½ abort() 被è°ç¨æ¶ï¼
controller.signalå°±ä¼è§¦åabortäºä»¶ãcontroller.signal.aborted屿§å为trueã
éå¸¸ï¼æä»¬éè¦å¤ç两é¨åï¼
- ä¸é¨åæ¯éè¿å¨
controller.signal䏿·»å ä¸ä¸ªçå¬å¨ï¼æ¥æ§è¡å¯åæ¶æä½ã - å¦ä¸é¨åæ¯è§¦ååæ¶ï¼å¨éè¦çæ¶åè°ç¨
controller.abort()ã
è¿æ¯å®æ´ç示ä¾ï¼ç®åè¿æ²¡æ fetchï¼ï¼
let controller = new AbortController();
let signal = controller.signal;
// æ§è¡å¯åæ¶æä½é¨å
// è·å "signal" 对象ï¼
// å¹¶å°çå¬å¨è®¾ç½®ä¸ºå¨ controller.abort() 被è°ç¨æ¶è§¦å
signal.addEventListener('abort', () => alert("abort!"));
// å¦ä¸é¨åï¼åæ¶ï¼å¨ä¹åç任使¶åï¼ï¼
controller.abort(); // 䏿¢ï¼
// äºä»¶è§¦åï¼signal.aborted å为 true
alert(signal.aborted); // true
æ£å¦æä»¬æçå°çï¼AbortController åªæ¯å¨ abort() 被è°ç¨æ¶ä¼ é abort äºä»¶çä¸ç§æ¹å¼ã
æä»¬å¯ä»¥èªå·±å¨ä»£ç ä¸å®ç°ç¸åç±»åçäºä»¶çå¬ï¼èä¸éè¦ AbortController 对象ã
使¯æä»·å¼çæ¯ï¼fetch ç¥éå¦ä½ä¸ AbortController 对象ä¸èµ·å·¥ä½ãå®ä»¬æ¯éæå¨ä¸èµ·çã
ä¸ fetch ä¸èµ·ä½¿ç¨
为äºè½å¤åæ¶ fetchï¼è¯·å° AbortController ç signal 屿§ä½ä¸º fetch çä¸ä¸ªå¯éåæ°ï¼optionï¼è¿è¡ä¼ éï¼
let controller = new AbortController();
fetch(url, {
signal: controller.signal
});
fetch æ¹æ³ç¥éå¦ä½ä¸ AbortController ä¸èµ·å·¥ä½ãå®ä¼çå¬ signal ä¸ç abort äºä»¶ã
ç°å¨ï¼æ³è¦ä¸æ¢ fetchï¼è°ç¨ controller.abort() å³å¯ï¼
controller.abort();
æä»¬å®æå¦ï¼fetch ä» signal è·åäºäºä»¶å¹¶ä¸æ¢äºè¯·æ±ã
å½ä¸ä¸ª fetch è¢«ä¸æ¢ï¼å®ç promise å°±ä¼ä»¥ä¸ä¸ª error AbortError rejectï¼å æ¤æä»¬åºè¯¥å¯¹å
¶è¿è¡å¤çï¼ä¾å¦å¨ try..catch ä¸ã
è¿æ¯å®æ´ç示ä¾ï¼å
¶ä¸ fetch å¨ 1 ç§å䏿¢ï¼
// 1 ç§å䏿¢
let controller = new AbortController();
setTimeout(() => controller.abort(), 1000);
try {
let response = await fetch('/article/fetch-abort/demo/hang', {
signal: controller.signal
});
} catch(err) {
if (err.name == 'AbortError') { // handle abort()
alert("Aborted!");
} else {
throw err;
}
}
AbortController æ¯å¯ä¼¸ç¼©ç
AbortController æ¯å¯ä¼¸ç¼©çãå®å
è®¸ä¸æ¬¡åæ¶å¤ä¸ª fetchã
è¿æ¯ä¸ä¸ªä»£ç è稿ï¼è¯¥ä»£ç å¹¶è¡ fetch å¾å¤ urlsï¼å¹¶ä½¿ç¨å个æ§å¶å¨å°å
¶å
¨é¨ä¸æ¢ï¼
let urls = [...]; // è¦å¹¶è¡ fetch ç url å表
let controller = new AbortController();
// ä¸ä¸ª fetch promise çæ°ç»
let fetchJobs = urls.map(url => fetch(url, {
signal: controller.signal
}));
let results = await Promise.all(fetchJobs);
// controller.abort() 被ä»ä»»ä½å°æ¹è°ç¨ï¼
// å®é½å°ä¸æ¢ææ fetch
妿æä»¬æèªå·±çä¸ fetch ä¸åç弿¥ä»»å¡ï¼æä»¬å¯ä»¥ä½¿ç¨å个 AbortController 䏿¢è¿äºä»»å¡ä»¥å fetchã
卿们çä»»å¡ä¸ï¼æä»¬åªéè¦çå¬å
¶ abort äºä»¶ï¼
let urls = [...];
let controller = new AbortController();
let ourJob = new Promise((resolve, reject) => { // æä»¬çä»»å¡
...
controller.signal.addEventListener('abort', reject);
});
let fetchJobs = urls.map(url => fetch(url, { // fetches
signal: controller.signal
}));
// çå¾
宿æä»¬çä»»å¡åææ fetch
let results = await Promise.all([...fetchJobs, ourJob]);
// controller.abort() 被ä»ä»»ä½å°æ¹è°ç¨ï¼
// å®é½å°ä¸æ¢ææ fetch å ourJob
æ»ç»
AbortControlleræ¯ä¸ä¸ªç®åç对象ï¼å½abort()æ¹æ³è¢«è°ç¨æ¶ï¼ä¼å¨èªèº«çsignal屿§ä¸çæabortäºä»¶ï¼å¹¶å°signal.aborted设置为trueï¼ãfetchä¸ä¹éæï¼æä»¬å°signal屿§ä½ä¸ºå¯éåæ°ï¼optionï¼è¿è¡ä¼ éï¼ä¹åfetchä¼çå¬å®ï¼å æ¤å®è½å¤ä¸æ¢fetchã- æä»¬å¯ä»¥å¨æä»¬ç代ç ä¸ä½¿ç¨
AbortControllerãâè°ç¨abort()â â âçå¬abortäºä»¶â交äºç®åä¸éç¨ãå³ä½¿æ²¡æfetchï¼æä»¬ä¹å¯ä»¥ä½¿ç¨å®ã
è¯è®º
<code>æ ç¾æå ¥åªæå 个è¯ç代ç ï¼æå ¥å¤è¡ä»£ç å¯ä»¥ä½¿ç¨<pre>æ ç¾ï¼å¯¹äºè¶ è¿ 10 è¡ç代ç ï¼å»ºè®®ä½ ä½¿ç¨æ²ç®±ï¼plnkrï¼JSBinï¼codepenâ¦ï¼