首页 文章 精选 留言 我的

精选列表

搜索[JavaScript库],共10000篇文章
优秀的个人博客,低调大师

JavaScript 中的 AbortController:如何优雅地取消 fetch 与异步任务

在开发中我们经常遇到这样的场景:用户快速切换页面,但之前的接口请求还在进行;搜索框连续输入时,每敲一个字符就发一次请求,旧请求的结果可能覆盖新结果;或者文件上传过程中用户点击了取消按钮。这些情况如果不做处理,轻则浪费带宽和服务器资源,重则导致界面状态混乱。过去我们常用一个布尔标记或 XMLHttpRequest 的 abort 方法来中断请求,但代码零散且难以复用于 Promise 链。AbortController 是现代浏览器提供的标准 API,它让取消操作变得统一且可组合。这篇文章会从实际代码出发,讲清楚 AbortController 的基本用法、如何配合 fetch 取消请求、如何处理多个请求共用一个信号、以及它在非 fetch 异步任务中的巧妙应用。 ## 基本用法 AbortController 的接口非常简洁。创建一个控制器实例后,通过 `controller.signal` 拿到一个 AbortSignal 对象,把它传给需要取消的操作。调用 `controller.abort()` 就会触发 signal 上的 abort 事件。 ```js const controller = new AbortController(); const { signal } = controller; signal.addEventListener('abort', () => { console.log('操作被取消了'); }); controller.abort(); // 输出:操作被取消了 ``` 你可以通过 `signal.aborted` 判断是否已经取消。这个布尔值在调用 abort 后会永久变为 true。 ## 取消 fetch 请求 fetch 从设计之初就支持传入 signal。 ```js async function fetchData(url) { const controller = new AbortController(); const { signal } = controller; // 设置超时,比如 5 秒后自动取消 const timeoutId = setTimeout(() => controller.abort(), 5000); try { const response = await fetch(url, { signal }); const data = await response.json(); return data; } catch (err) { if (err.name === 'AbortError') { console.log('请求被取消或超时'); } else { throw err; } } finally { clearTimeout(timeoutId); } } ``` 要注意的是,当请求被 abort 时,fetch 返回的 Promise 会 reject 一个 name 为 `AbortError` 的 DOMException。你需要区分这个错误和网络错误。 ## 处理连续请求的竞态问题 搜索框输入联想是典型场景。每次输入都发请求,但返回顺序不确定。用 AbortController 可以保证只处理最后一次请求。 ```js let currentController = null; async function search(keyword) { if (currentController) { currentController.abort(); } currentController = new AbortController(); const { signal } = currentController; try { const res = await fetch(`/api/search?q=${encodeURIComponent(keyword)}`, { signal }); const list = await res.json(); renderList(list); } catch (err) { if (err.name !== 'AbortError') { console.error('搜索失败', err); } } } ``` 这里的关键是每次新请求前取消上一个控制器。如果上一个请求已经完成,abort 不会有任何副作用。 ## 多个请求共享一个信号 有时候我们需要一次性取消一组请求,比如页面卸载时取消所有进行中的请求。可以让多个 fetch 使用同一个 signal。 ```js const controller = new AbortController(); const { signal } = controller; const p1 = fetch('/api/a', { signal }); const p2 = fetch('/api/b', { signal }); // 组件卸载时 controller.abort(); // p1 和 p2 都会收到取消 ``` 但要注意,一旦 abort 被调用,这个 signal 就永久处于已取消状态,不能复用。需要重新创建控制器。 ## 让自定义异步任务支持取消 AbortController 不仅用于 fetch。你可以让任何异步操作监听 signal 的 abort 事件,然后主动清理或拒绝。 例如,一个模拟的延时任务: ```js function delay(ms, signal) { return new Promise((resolve, reject) => { const timer = setTimeout(resolve, ms); signal.addEventListener('abort', () => { clearTimeout(timer); reject(new DOMException('Aborted', 'AbortError')); }); }); } const controller = new AbortController(); const { signal } = controller; delay(3000, signal).then(() => console.log('完成')).catch(err => { if (err.name === 'AbortError') { console.log('延时被取消'); } }); setTimeout(() => controller.abort(), 1000); // 1 秒后取消 ``` 真实项目中,你可能会封装 websocket 连接、轮询逻辑或者文件读取,都可以用同样的方式接入 signal。 ## 与 Promise.race 的取舍 以前我们常用 Promise.race 来实现超时,比如 `Promise.race([fetch(url), timeout(5000)])`。但这种方式并不能真正取消底层的 fetch 请求,只是让外层的 Promise 提前结束,网络请求依然在继续。AbortController 能真正中断请求,释放连接资源。所以在需要取消的场景下,优先使用 AbortController。 ## 兼容性与 polyfill AbortController 在现代浏览器中支持良好。如果你需要支持较老的浏览器,可以引入 `abortcontroller-polyfill`。不过要注意,polyfill 无法取消原生的 fetch,只能让 API 存在,真正取消请求仍然需要浏览器支持。对于 Node.js,从 v15 开始也提供了全局的 AbortController(之前需要通过 `require('abort-controller')` 引入)。 ## 一些容易踩的坑 - 不要复用已经 abort 的 signal,一定要新建控制器。 - 在 catch 中一定要判断 `err.name === 'AbortError'`,不要把它当成真正的错误上报。 - 使用 `signal.throwIfAborted()` 可以在代码中快速抛出 AbortError(如果环境支持)。 - 如果同一个 signal 传给多个 fetch,其中一个被 abort 后,其他也会立即被取消,这是符合预期的。 - 在清理函数中移除事件监听,虽然 signal 本身是弱引用,但在一些长期存在的 signal 上仍建议用 `signal.addEventListener` 后适时移除,避免内存泄漏。 AbortController 让取消操作变成一种可传递、可组合的能力。下次写异步逻辑时,不妨把它作为默认的取消方案。 推荐查看天气:https://www.40tianqi.com/changning/40tian.html 推荐查看天气:https://www.40tianqi.com/zhaotong/ 推荐查看天气:https://www.40tianqi.com/zhaotong/zuotian.html 推荐查看天气:https://www.40tianqi.com/zhaotong/7tian.html 推荐查看天气:https://www.40tianqi.com/zhaotong/10tian.html 推荐查看天气:https://www.40tianqi.com/zhaotong/15tian.html 推荐查看天气:https://www.40tianqi.com/zhaotong/40tian.html 推荐查看天气:https://www.40tianqi.com/zhaoyang/ 推荐查看天气:https://www.40tianqi.com/zhaoyang/zuotian.html 推荐查看天气:https://www.40tianqi.com/zhaoyang/7tian.html 推荐查看天气:https://www.40tianqi.com/zhaoyang/10tian.html 推荐查看天气:https://www.40tianqi.com/zhaoyang/15tian.html 推荐查看天气:https://www.40tianqi.com/zhaoyang/40tian.html 推荐查看天气:https://www.40tianqi.com/ludian/ 推荐查看天气:https://www.40tianqi.com/ludian/zuotian.html 推荐查看天气:https://www.40tianqi.com/ludian/7tian.html 推荐查看天气:https://www.40tianqi.com/ludian/10tian.html 推荐查看天气:https://www.40tianqi.com/ludian/15tian.html 推荐查看天气:https://www.40tianqi.com/ludian/40tian.html 推荐查看天气:https://www.40tianqi.com/qiaojia/ 推荐查看天气:https://www.40tianqi.com/qiaojia/zuotian.html 推荐查看天气:https://www.40tianqi.com/qiaojia/7tian.html 推荐查看天气:https://www.40tianqi.com/qiaojia/10tian.html 推荐查看天气:https://www.40tianqi.com/qiaojia/15tian.html 推荐查看天气:https://www.40tianqi.com/qiaojia/40tian.html 推荐查看天气:https://www.40tianqi.com/yanjin/ 推荐查看天气:https://www.40tianqi.com/yanjin/zuotian.html 推荐查看天气:https://www.40tianqi.com/yanjin/7tian.html 推荐查看天气:https://www.40tianqi.com/yanjin/10tian.html 推荐查看天气:https://www.40tianqi.com/yanjin/15tian.html 推荐查看天气:https://www.40tianqi.com/yanjin/40tian.html 推荐查看天气:https://www.40tianqi.com/daguan/ 推荐查看天气:https://www.40tianqi.com/daguan/zuotian.html 推荐查看天气:https://www.40tianqi.com/daguan/7tian.html 推荐查看天气:https://www.40tianqi.com/daguan/10tian.html 推荐查看天气:https://www.40tianqi.com/daguan/15tian.html 推荐查看天气:https://www.40tianqi.com/daguan/40tian.html 推荐查看天气:https://www.40tianqi.com/yongshan/ 推荐查看天气:https://www.40tianqi.com/yongshan/zuotian.html 推荐查看天气:https://www.40tianqi.com/yongshan/7tian.html 推荐查看天气:https://www.40tianqi.com/yongshan/10tian.html 推荐查看天气:https://www.40tianqi.com/yongshan/15tian.html 推荐查看天气:https://www.40tianqi.com/yongshan/40tian.html 推荐查看天气:https://www.40tianqi.com/suijiang/ 推荐查看天气:https://www.40tianqi.com/suijiang/zuotian.html 推荐查看天气:https://www.40tianqi.com/suijiang/7tian.html 推荐查看天气:https://www.40tianqi.com/suijiang/10tian.html 推荐查看天气:https://www.40tianqi.com/suijiang/15tian.html 推荐查看天气:https://www.40tianqi.com/suijiang/40tian.html 推荐查看天气:https://www.40tianqi.com/zhenxiong/ 推荐查看天气:https://www.40tianqi.com/zhenxiong/zuotian.html 推荐查看天气:https://www.40tianqi.com/zhenxiong/7tian.html 推荐查看天气:https://www.40tianqi.com/zhenxiong/10tian.html 推荐查看天气:https://www.40tianqi.com/zhenxiong/15tian.html 推荐查看天气:https://www.40tianqi.com/zhenxiong/40tian.html 推荐查看天气:https://www.40tianqi.com/yiliang/ 推荐查看天气:https://www.40tianqi.com/yiliang/zuotian.html 推荐查看天气:https://www.40tianqi.com/yiliang/7tian.html 推荐查看天气:https://www.40tianqi.com/yiliang/10tian.html 推荐查看天气:https://www.40tianqi.com/yiliang/15tian.html 推荐查看天气:https://www.40tianqi.com/yiliang/40tian.html 推荐查看天气:https://www.40tianqi.com/weixin/ 推荐查看天气:https://www.40tianqi.com/weixin/zuotian.html 推荐查看天气:https://www.40tianqi.com/weixin/7tian.html 推荐查看天气:https://www.40tianqi.com/weixin/10tian.html 推荐查看天气:https://www.40tianqi.com/weixin/15tian.html 推荐查看天气:https://www.40tianqi.com/weixin/40tian.html 推荐查看天气:https://www.40tianqi.com/shuifu/ 推荐查看天气:https://www.40tianqi.com/shuifu/zuotian.html 推荐查看天气:https://www.40tianqi.com/shuifu/7tian.html 推荐查看天气:https://www.40tianqi.com/shuifu/10tian.html 推荐查看天气:https://www.40tianqi.com/shuifu/15tian.html 推荐查看天气:https://www.40tianqi.com/shuifu/40tian.html 推荐查看天气:https://www.40tianqi.com/lijiang/ 推荐查看天气:https://www.40tianqi.com/lijiang/zuotian.html 推荐查看天气:https://www.40tianqi.com/lijiang/7tian.html 推荐查看天气:https://www.40tianqi.com/lijiang/10tian.html 推荐查看天气:https://www.40tianqi.com/lijiang/15tian.html 推荐查看天气:https://www.40tianqi.com/lijiang/40tian.html 推荐查看天气:https://www.40tianqi.com/gucheng/ 推荐查看天气:https://www.40tianqi.com/gucheng/zuotian.html 推荐查看天气:https://www.40tianqi.com/gucheng/7tian.html 推荐查看天气:https://www.40tianqi.com/gucheng/10tian.html 推荐查看天气:https://www.40tianqi.com/gucheng/15tian.html 推荐查看天气:https://www.40tianqi.com/gucheng/40tian.html 推荐查看天气:https://www.40tianqi.com/yulong/ 推荐查看天气:https://www.40tianqi.com/yulong/zuotian.html 推荐查看天气:https://www.40tianqi.com/yulong/7tian.html 推荐查看天气:https://www.40tianqi.com/yulong/10tian.html 推荐查看天气:https://www.40tianqi.com/yulong/15tian.html 推荐查看天气:https://www.40tianqi.com/yulong/40tian.html 推荐查看天气:https://www.40tianqi.com/yongsheng/ 推荐查看天气:https://www.40tianqi.com/yongsheng/zuotian.html 推荐查看天气:https://www.40tianqi.com/yongsheng/7tian.html 推荐查看天气:https://www.40tianqi.com/yongsheng/10tian.html 推荐查看天气:https://www.40tianqi.com/yongsheng/15tian.html 推荐查看天气:https://www.40tianqi.com/yongsheng/40tian.html 推荐查看天气:https://www.40tianqi.com/huaping/ 推荐查看天气:https://www.40tianqi.com/huaping/zuotian.html 推荐查看天气:https://www.40tianqi.com/huaping/7tian.html 推荐查看天气:https://www.40tianqi.com/huaping/10tian.html 推荐查看天气:https://www.40tianqi.com/huaping/15tian.html 推荐查看天气:https://www.40tianqi.com/huaping/40tian.html 推荐查看天气:https://www.40tianqi.com/ninglang/ 推荐查看天气:https://www.40tianqi.com/ninglang/zuotian.html 推荐查看天气:https://www.40tianqi.com/ninglang/7tian.html 推荐查看天气:https://www.40tianqi.com/ninglang/10tian.html 推荐查看天气:https://www.40tianqi.com/ninglang/15tian.html 推荐查看天气:https://www.40tianqi.com/ninglang/40tian.html 推荐查看天气:https://www.40tianqi.com/puer/ 推荐查看天气:https://www.40tianqi.com/puer/zuotian.html 推荐查看天气:https://www.40tianqi.com/puer/7tian.html 推荐查看天气:https://www.40tianqi.com/puer/10tian.html 推荐查看天气:https://www.40tianqi.com/puer/15tian.html 推荐查看天气:https://www.40tianqi.com/puer/40tian.html 推荐查看天气:https://www.40tianqi.com/simao/ 推荐查看天气:https://www.40tianqi.com/simao/zuotian.html 推荐查看天气:https://www.40tianqi.com/simao/7tian.html 推荐查看天气:https://www.40tianqi.com/simao/10tian.html 推荐查看天气:https://www.40tianqi.com/simao/15tian.html 推荐查看天气:https://www.40tianqi.com/simao/40tian.html 推荐查看天气:https://www.40tianqi.com/ninger/ 推荐查看天气:https://www.40tianqi.com/ninger/zuotian.html 推荐查看天气:https://www.40tianqi.com/ninger/7tian.html 推荐查看天气:https://www.40tianqi.com/ninger/10tian.html 推荐查看天气:https://www.40tianqi.com/ninger/15tian.html 推荐查看天气:https://www.40tianqi.com/ninger/40tian.html 推荐查看天气:https://www.40tianqi.com/mojiang/ 推荐查看天气:https://www.40tianqi.com/mojiang/zuotian.html 推荐查看天气:https://www.40tianqi.com/mojiang/7tian.html 推荐查看天气:https://www.40tianqi.com/mojiang/10tian.html 推荐查看天气:https://www.40tianqi.com/mojiang/15tian.html 推荐查看天气:https://www.40tianqi.com/mojiang/40tian.html 推荐查看天气:https://www.40tianqi.com/jingdong/ 推荐查看天气:https://www.40tianqi.com/jingdong/zuotian.html 推荐查看天气:https://www.40tianqi.com/jingdong/7tian.html 推荐查看天气:https://www.40tianqi.com/jingdong/10tian.html 推荐查看天气:https://www.40tianqi.com/jingdong/15tian.html 推荐查看天气:https://www.40tianqi.com/jingdong/40tian.html 推荐查看天气:https://www.40tianqi.com/jinggu/ 推荐查看天气:https://www.40tianqi.com/jinggu/zuotian.html 推荐查看天气:https://www.40tianqi.com/jinggu/7tian.html 推荐查看天气:https://www.40tianqi.com/jinggu/10tian.html 推荐查看天气:https://www.40tianqi.com/jinggu/15tian.html 推荐查看天气:https://www.40tianqi.com/jinggu/40tian.html 推荐查看天气:https://www.40tianqi.com/simaozhenyuan/ 推荐查看天气:https://www.40tianqi.com/simaozhenyuan/zuotian.html 推荐查看天气:https://www.40tianqi.com/simaozhenyuan/7tian.html 推荐查看天气:https://www.40tianqi.com/simaozhenyuan/10tian.html 推荐查看天气:https://www.40tianqi.com/simaozhenyuan/15tian.html 推荐查看天气:https://www.40tianqi.com/simaozhenyuan/40tian.html 推荐查看天气:https://www.40tianqi.com/jiangcheng/ 推荐查看天气:https://www.40tianqi.com/jiangcheng/zuotian.html 推荐查看天气:https://www.40tianqi.com/jiangcheng/7tian.html 推荐查看天气:https://www.40tianqi.com/jiangcheng/10tian.html 推荐查看天气:https://www.40tianqi.com/jiangcheng/15tian.html 推荐查看天气:https://www.40tianqi.com/jiangcheng/40tian.html 推荐查看天气:https://www.40tianqi.com/menglian/ 推荐查看天气:https://www.40tianqi.com/menglian/zuotian.html 推荐查看天气:https://www.40tianqi.com/menglian/7tian.html 推荐查看天气:https://www.40tianqi.com/menglian/10tian.html 推荐查看天气:https://www.40tianqi.com/menglian/15tian.html 推荐查看天气:https://www.40tianqi.com/menglian/40tian.html 推荐查看天气:https://www.40tianqi.com/lancang/ 推荐查看天气:https://www.40tianqi.com/lancang/zuotian.html 推荐查看天气:https://www.40tianqi.com/lancang/7tian.html 推荐查看天气:https://www.40tianqi.com/lancang/10tian.html 推荐查看天气:https://www.40tianqi.com/lancang/15tian.html 推荐查看天气:https://www.40tianqi.com/lancang/40tian.html 推荐查看天气:https://www.40tianqi.com/ximeng/ 推荐查看天气:https://www.40tianqi.com/ximeng/zuotian.html 推荐查看天气:https://www.40tianqi.com/ximeng/7tian.html 推荐查看天气:https://www.40tianqi.com/ximeng/10tian.html 推荐查看天气:https://www.40tianqi.com/ximeng/15tian.html 推荐查看天气:https://www.40tianqi.com/ximeng/40tian.html 推荐查看天气:https://www.40tianqi.com/lincang/ 推荐查看天气:https://www.40tianqi.com/lincang/zuotian.html 推荐查看天气:https://www.40tianqi.com/lincang/7tian.html 推荐查看天气:https://www.40tianqi.com/lincang/10tian.html 推荐查看天气:https://www.40tianqi.com/lincang/15tian.html 推荐查看天气:https://www.40tianqi.com/lincang/40tian.html 推荐查看天气:https://www.40tianqi.com/linxiang/ 推荐查看天气:https://www.40tianqi.com/linxiang/zuotian.html 推荐查看天气:https://www.40tianqi.com/linxiang/7tian.html 推荐查看天气:https://www.40tianqi.com/linxiang/10tian.html 推荐查看天气:https://www.40tianqi.com/linxiang/15tian.html 推荐查看天气:https://www.40tianqi.com/linxiang/40tian.html 推荐查看天气:https://www.40tianqi.com/fengqing/ 推荐查看天气:https://www.40tianqi.com/fengqing/zuotian.html 推荐查看天气:https://www.40tianqi.com/fengqing/7tian.html 推荐查看天气:https://www.40tianqi.com/fengqing/10tian.html 推荐查看天气:https://www.40tianqi.com/fengqing/15tian.html 推荐查看天气:https://www.40tianqi.com/fengqing/40tian.html 推荐查看天气:https://www.40tianqi.com/yunxian/ 推荐查看天气:https://www.40tianqi.com/yunxian/zuotian.html 推荐查看天气:https://www.40tianqi.com/yunxian/7tian.html 推荐查看天气:https://www.40tianqi.com/yunxian/10tian.html 推荐查看天气:https://www.40tianqi.com/yunxian/15tian.html 推荐查看天气:https://www.40tianqi.com/yunxian/40tian.html 推荐查看天气:https://www.40tianqi.com/yongde/

优秀的个人博客,低调大师

JavaScript 事件循环里微任务和渲染帧的真实关系

先明确一个容易混的点:浏览器的主线程同一时间只能做一件事,事件循环负责调度任务。规范把任务分成 task 和 microtask,task 来自不同的 task source(比如用户交互、网络、定时器),每个 task source 有自己的队列。每一轮循环只从某个 task 队列里取一个 task 执行,执行完后执行 microtask checkpoint,即把微任务队列清空。清空之后,浏览器会判断是否需要 render,需要的话就走样式计算、布局、绘制、合成。render 不是 task,它发生在当前 task 和微任务都处理完之后。 看一段代码: ```html ``` 同步代码里连续修改样式并读取 `offsetWidth`,每次都触发强制同步布局,因为读取布局属性本身就是同步操作,浏览器必须立刻把最新样式算完才能返回准确值。这里没有任务切换,所以和微任务无关。 真正容易踩坑的是把 DOM 操作放进微任务: ```js box.style.width = '100px'; Promise.resolve().then(() => { box.style.width = '200px'; }); console.log(box.offsetWidth); // 100 ``` `console.log` 在同步代码里执行,微任务还没跑,读到的是 100。等当前 task 的同步代码结束,微任务才执行,把宽度改成 200。之后浏览器才进入渲染流程。所以微任务里的样式修改会在同一帧被应用,不会丢到下一帧。 那为什么有时会感觉微任务里的 DOM 读取布局不准?因为顺序问题: ```js Promise.resolve().then(() => { box.style.width = '200px'; }); Promise.resolve().then(() => { console.log(box.offsetWidth); // 200 }); ``` 同一个微任务队列里按注册顺序执行,第一个微任务改样式,第二个微任务读布局,读到的是改完的值,因为第一个微任务结束时并没有进入渲染,但 DOM 的 style 已经是新值,读取布局会触发同步计算。这里没有跨帧。 再看和 `requestAnimationFrame` 的关系。`requestAnimationFrame` 的回调属于渲染流程的一部分,规范里它是在 render 之前的「run the animation frame callbacks」步骤执行。它既不是普通 task,也不是 microtask。执行顺序大致是:当前 task → microtask 清空 → requestAnimationFrame 回调 → style/layout/paint。 ```js console.log('A'); setTimeout(() => console.log('B'), 0); Promise.resolve().then(() => console.log('C')); requestAnimationFrame(() => console.log('D')); console.log('E'); ``` 输出顺序通常是 A、E、C、D、B。同步代码先跑完,微任务 C 在渲染前执行,然后 rAF 回调 D,最后才是下一个宏任务 B。如果浏览器当前帧没有安排渲染,rAF 可能会延迟到下一帧,但微任务永远在 rAF 之前。 有个实际场景:用微任务改完 DOM 后,想在下一帧读取最终布局并做后续计算。如果直接在微任务里读,会触发同步布局,虽然值是对的,但可能造成不必要的性能开销。更好的做法是把读取放到 `requestAnimationFrame`: ```js function updateWidth(next) { box.style.width = next + 'px'; requestAnimationFrame(() => { const rect = box.getBoundingClientRect(); console.log('布局后的宽度', rect.width); }); } Promise.resolve().then(() => updateWidth(400)); ``` 微任务里写样式,rAF 里读布局,读写分离,避免同步布局抖动。 另一个坑是微任务里的无限追加: ```js function loop() { Promise.resolve().then(loop); } loop(); ``` 这会一直往微任务队列里塞新微任务,微任务 checkpoint 永远清不完,浏览器无法进入渲染,页面直接卡死。`setTimeout` 递归不会这样,因为每次都是新的宏任务,中间有机会渲染。 `queueMicrotask` 和 `Promise.then` 在调度上等价,它只是更显式。如果只是想把一段逻辑放到当前同步代码之后、渲染之前执行,用 `queueMicrotask` 更清楚。 `requestIdleCallback` 又不一样,它在渲染之后的空闲时间执行,优先级最低。别指望它在微任务或 rAF 之前跑。 ```js Promise.resolve().then(() => console.log('micro')); requestAnimationFrame(() => console.log('raf')); requestIdleCallback(() => console.log('idle')); ``` 顺序是 micro、raf、idle。 理解这套顺序后,处理「读写成对」就简单了:需要同步读布局就同步读,接受强制布局的成本;需要批量写再异步读,就写进微任务、读进 rAF;需要等所有渲染完成再做低优先级工作,就用 requestIdleCallback。别把微任务当成「下一帧」,它是当前 task 的尾巴,渲染还没发生。 推荐查看天气:https://www.0dtq.com/shibei/15tian.html 推荐查看天气:https://www.0dtq.com/shibei/40tian.html 推荐查看天气:https://www.0dtq.com/huangdao/ 推荐查看天气:https://www.0dtq.com/huangdao/zuotian.html 推荐查看天气:https://www.0dtq.com/huangdao/7tian.html 推荐查看天气:https://www.0dtq.com/huangdao/10tian.html 推荐查看天气:https://www.0dtq.com/huangdao/15tian.html 推荐查看天气:https://www.0dtq.com/huangdao/40tian.html 推荐查看天气:https://www.0dtq.com/laoshan/ 推荐查看天气:https://www.0dtq.com/laoshan/zuotian.html 推荐查看天气:https://www.0dtq.com/laoshan/7tian.html 推荐查看天气:https://www.0dtq.com/laoshan/10tian.html 推荐查看天气:https://www.0dtq.com/laoshan/15tian.html 推荐查看天气:https://www.0dtq.com/laoshan/40tian.html 推荐查看天气:https://www.0dtq.com/licang/ 推荐查看天气:https://www.0dtq.com/licang/zuotian.html 推荐查看天气:https://www.0dtq.com/licang/7tian.html 推荐查看天气:https://www.0dtq.com/licang/10tian.html 推荐查看天气:https://www.0dtq.com/licang/15tian.html 推荐查看天气:https://www.0dtq.com/licang/40tian.html 推荐查看天气:https://www.0dtq.com/chengyang/ 推荐查看天气:https://www.0dtq.com/chengyang/zuotian.html 推荐查看天气:https://www.0dtq.com/chengyang/7tian.html 推荐查看天气:https://www.0dtq.com/chengyang/10tian.html 推荐查看天气:https://www.0dtq.com/chengyang/15tian.html 推荐查看天气:https://www.0dtq.com/chengyang/40tian.html 推荐查看天气:https://www.0dtq.com/jiaozhou/ 推荐查看天气:https://www.0dtq.com/jiaozhou/zuotian.html 推荐查看天气:https://www.0dtq.com/jiaozhou/7tian.html 推荐查看天气:https://www.0dtq.com/jiaozhou/10tian.html 推荐查看天气:https://www.0dtq.com/jiaozhou/15tian.html 推荐查看天气:https://www.0dtq.com/jiaozhou/40tian.html 推荐查看天气:https://www.0dtq.com/jimo/ 推荐查看天气:https://www.0dtq.com/jimo/zuotian.html 推荐查看天气:https://www.0dtq.com/jimo/7tian.html 推荐查看天气:https://www.0dtq.com/jimo/10tian.html 推荐查看天气:https://www.0dtq.com/jimo/15tian.html 推荐查看天气:https://www.0dtq.com/jimo/40tian.html 推荐查看天气:https://www.0dtq.com/pingdu/ 推荐查看天气:https://www.0dtq.com/pingdu/zuotian.html 推荐查看天气:https://www.0dtq.com/pingdu/7tian.html 推荐查看天气:https://www.0dtq.com/pingdu/10tian.html 推荐查看天气:https://www.0dtq.com/pingdu/15tian.html 推荐查看天气:https://www.0dtq.com/pingdu/40tian.html 推荐查看天气:https://www.0dtq.com/jiaonan/ 推荐查看天气:https://www.0dtq.com/jiaonan/zuotian.html 推荐查看天气:https://www.0dtq.com/jiaonan/7tian.html 推荐查看天气:https://www.0dtq.com/jiaonan/10tian.html 推荐查看天气:https://www.0dtq.com/jiaonan/15tian.html 推荐查看天气:https://www.0dtq.com/jiaonan/40tian.html 推荐查看天气:https://www.0dtq.com/laixi/ 推荐查看天气:https://www.0dtq.com/laixi/zuotian.html 推荐查看天气:https://www.0dtq.com/laixi/7tian.html 推荐查看天气:https://www.0dtq.com/laixi/10tian.html 推荐查看天气:https://www.0dtq.com/laixi/15tian.html 推荐查看天气:https://www.0dtq.com/laixi/40tian.html 推荐查看天气:https://www.0dtq.com/zibo/ 推荐查看天气:https://www.0dtq.com/zibo/zuotian.html 推荐查看天气:https://www.0dtq.com/zibo/7tian.html 推荐查看天气:https://www.0dtq.com/zibo/10tian.html 推荐查看天气:https://www.0dtq.com/zibo/15tian.html 推荐查看天气:https://www.0dtq.com/zibo/40tian.html 推荐查看天气:https://www.0dtq.com/zichuan/ 推荐查看天气:https://www.0dtq.com/zichuan/zuotian.html 推荐查看天气:https://www.0dtq.com/zichuan/7tian.html 推荐查看天气:https://www.0dtq.com/zichuan/10tian.html 推荐查看天气:https://www.0dtq.com/zichuan/15tian.html 推荐查看天气:https://www.0dtq.com/zichuan/40tian.html 推荐查看天气:https://www.0dtq.com/zhangdian/ 推荐查看天气:https://www.0dtq.com/zhangdian/zuotian.html 推荐查看天气:https://www.0dtq.com/zhangdian/7tian.html 推荐查看天气:https://www.0dtq.com/zhangdian/10tian.html 推荐查看天气:https://www.0dtq.com/zhangdian/15tian.html 推荐查看天气:https://www.0dtq.com/zhangdian/40tian.html 推荐查看天气:https://www.0dtq.com/boshan/ 推荐查看天气:https://www.0dtq.com/boshan/zuotian.html 推荐查看天气:https://www.0dtq.com/boshan/7tian.html 推荐查看天气:https://www.0dtq.com/boshan/10tian.html 推荐查看天气:https://www.0dtq.com/boshan/15tian.html 推荐查看天气:https://www.0dtq.com/boshan/40tian.html 推荐查看天气:https://www.0dtq.com/linzi/ 推荐查看天气:https://www.0dtq.com/linzi/zuotian.html 推荐查看天气:https://www.0dtq.com/linzi/7tian.html 推荐查看天气:https://www.0dtq.com/linzi/10tian.html 推荐查看天气:https://www.0dtq.com/linzi/15tian.html 推荐查看天气:https://www.0dtq.com/linzi/40tian.html 推荐查看天气:https://www.0dtq.com/zhoucun/ 推荐查看天气:https://www.0dtq.com/zhoucun/zuotian.html 推荐查看天气:https://www.0dtq.com/zhoucun/7tian.html 推荐查看天气:https://www.0dtq.com/zhoucun/10tian.html 推荐查看天气:https://www.0dtq.com/zhoucun/15tian.html 推荐查看天气:https://www.0dtq.com/zhoucun/40tian.html 推荐查看天气:https://www.0dtq.com/huantai/ 推荐查看天气:https://www.0dtq.com/huantai/zuotian.html 推荐查看天气:https://www.0dtq.com/huantai/7tian.html 推荐查看天气:https://www.0dtq.com/huantai/10tian.html 推荐查看天气:https://www.0dtq.com/huantai/15tian.html 推荐查看天气:https://www.0dtq.com/huantai/40tian.html 推荐查看天气:https://www.0dtq.com/gaoqing/ 推荐查看天气:https://www.0dtq.com/gaoqing/zuotian.html 推荐查看天气:https://www.0dtq.com/gaoqing/7tian.html 推荐查看天气:https://www.0dtq.com/gaoqing/10tian.html 推荐查看天气:https://www.0dtq.com/gaoqing/15tian.html 推荐查看天气:https://www.0dtq.com/gaoqing/40tian.html 推荐查看天气:https://www.0dtq.com/yiyuan/ 推荐查看天气:https://www.0dtq.com/yiyuan/zuotian.html 推荐查看天气:https://www.0dtq.com/yiyuan/7tian.html 推荐查看天气:https://www.0dtq.com/yiyuan/10tian.html 推荐查看天气:https://www.0dtq.com/yiyuan/15tian.html 推荐查看天气:https://www.0dtq.com/yiyuan/40tian.html 推荐查看天气:https://www.0dtq.com/zaozhuang/ 推荐查看天气:https://www.0dtq.com/zaozhuang/zuotian.html 推荐查看天气:https://www.0dtq.com/zaozhuang/7tian.html 推荐查看天气:https://www.0dtq.com/zaozhuang/10tian.html 推荐查看天气:https://www.0dtq.com/zaozhuang/15tian.html 推荐查看天气:https://www.0dtq.com/zaozhuang/40tian.html 推荐查看天气:https://www.0dtq.com/xuecheng/ 推荐查看天气:https://www.0dtq.com/xuecheng/zuotian.html 推荐查看天气:https://www.0dtq.com/xuecheng/7tian.html 推荐查看天气:https://www.0dtq.com/xuecheng/10tian.html 推荐查看天气:https://www.0dtq.com/xuecheng/15tian.html 推荐查看天气:https://www.0dtq.com/xuecheng/40tian.html 推荐查看天气:https://www.0dtq.com/zaozhuangyicheng/ 推荐查看天气:https://www.0dtq.com/zaozhuangyicheng/zuotian.html 推荐查看天气:https://www.0dtq.com/zaozhuangyicheng/7tian.html 推荐查看天气:https://www.0dtq.com/zaozhuangyicheng/10tian.html 推荐查看天气:https://www.0dtq.com/zaozhuangyicheng/15tian.html 推荐查看天气:https://www.0dtq.com/zaozhuangyicheng/40tian.html 推荐查看天气:https://www.0dtq.com/taierzhuang/ 推荐查看天气:https://www.0dtq.com/taierzhuang/zuotian.html 推荐查看天气:https://www.0dtq.com/taierzhuang/7tian.html 推荐查看天气:https://www.0dtq.com/taierzhuang/10tian.html 推荐查看天气:https://www.0dtq.com/taierzhuang/15tian.html 推荐查看天气:https://www.0dtq.com/taierzhuang/40tian.html 推荐查看天气:https://www.0dtq.com/shanting/ 推荐查看天气:https://www.0dtq.com/shanting/zuotian.html 推荐查看天气:https://www.0dtq.com/shanting/7tian.html 推荐查看天气:https://www.0dtq.com/shanting/10tian.html 推荐查看天气:https://www.0dtq.com/shanting/15tian.html 推荐查看天气:https://www.0dtq.com/shanting/40tian.html 推荐查看天气:https://www.0dtq.com/tengzhou/ 推荐查看天气:https://www.0dtq.com/tengzhou/zuotian.html 推荐查看天气:https://www.0dtq.com/tengzhou/7tian.html 推荐查看天气:https://www.0dtq.com/tengzhou/10tian.html 推荐查看天气:https://www.0dtq.com/tengzhou/15tian.html 推荐查看天气:https://www.0dtq.com/tengzhou/40tian.html 推荐查看天气:https://www.0dtq.com/dongying/ 推荐查看天气:https://www.0dtq.com/dongying/zuotian.html 推荐查看天气:https://www.0dtq.com/dongying/7tian.html 推荐查看天气:https://www.0dtq.com/dongying/10tian.html 推荐查看天气:https://www.0dtq.com/dongying/15tian.html 推荐查看天气:https://www.0dtq.com/dongying/40tian.html 推荐查看天气:https://www.0dtq.com/dongyinghekou/ 推荐查看天气:https://www.0dtq.com/dongyinghekou/zuotian.html 推荐查看天气:https://www.0dtq.com/dongyinghekou/7tian.html 推荐查看天气:https://www.0dtq.com/dongyinghekou/10tian.html 推荐查看天气:https://www.0dtq.com/dongyinghekou/15tian.html 推荐查看天气:https://www.0dtq.com/dongyinghekou/40tian.html 推荐查看天气:https://www.0dtq.com/kenli/ 推荐查看天气:https://www.0dtq.com/kenli/zuotian.html 推荐查看天气:https://www.0dtq.com/kenli/7tian.html 推荐查看天气:https://www.0dtq.com/kenli/10tian.html 推荐查看天气:https://www.0dtq.com/kenli/15tian.html 推荐查看天气:https://www.0dtq.com/kenli/40tian.html 推荐查看天气:https://www.0dtq.com/lijin/ 推荐查看天气:https://www.0dtq.com/lijin/zuotian.html 推荐查看天气:https://www.0dtq.com/lijin/7tian.html 推荐查看天气:https://www.0dtq.com/lijin/10tian.html 推荐查看天气:https://www.0dtq.com/lijin/15tian.html 推荐查看天气:https://www.0dtq.com/lijin/40tian.html 推荐查看天气:https://www.0dtq.com/guangrao/ 推荐查看天气:https://www.0dtq.com/guangrao/zuotian.html 推荐查看天气:https://www.0dtq.com/guangrao/7tian.html 推荐查看天气:https://www.0dtq.com/guangrao/10tian.html 推荐查看天气:https://www.0dtq.com/guangrao/15tian.html 推荐查看天气:https://www.0dtq.com/guangrao/40tian.html 推荐查看天气:https://www.0dtq.com/yantai/ 推荐查看天气:https://www.0dtq.com/yantai/zuotian.html 推荐查看天气:https://www.0dtq.com/yantai/7tian.html 推荐查看天气:https://www.0dtq.com/yantai/10tian.html 推荐查看天气:https://www.0dtq.com/yantai/15tian.html 推荐查看天气:https://www.0dtq.com/yantai/40tian.html 推荐查看天气:https://www.0dtq.com/zhifu/ 推荐查看天气:https://www.0dtq.com/zhifu/zuotian.html 推荐查看天气:https://www.0dtq.com/zhifu/7tian.html 推荐查看天气:https://www.0dtq.com/zhifu/10tian.html 推荐查看天气:https://www.0dtq.com/zhifu/15tian.html 推荐查看天气:https://www.0dtq.com/zhifu/40tian.html 推荐查看天气:https://www.0dtq.com/yantaifushan/ 推荐查看天气:https://www.0dtq.com/yantaifushan/zuotian.html 推荐查看天气:https://www.0dtq.com/yantaifushan/7tian.html 推荐查看天气:https://www.0dtq.com/yantaifushan/10tian.html 推荐查看天气:https://www.0dtq.com/yantaifushan/15tian.html 推荐查看天气:https://www.0dtq.com/yantaifushan/40tian.html 推荐查看天气:https://www.0dtq.com/mouping/ 推荐查看天气:https://www.0dtq.com/mouping/zuotian.html 推荐查看天气:https://www.0dtq.com/mouping/7tian.html 推荐查看天气:https://www.0dtq.com/mouping/10tian.html 推荐查看天气:https://www.0dtq.com/mouping/15tian.html 推荐查看天气:https://www.0dtq.com/mouping/40tian.html

优秀的个人博客,低调大师

JavaScript 中如何正确中断 Promise 链式调用并清理副作用

调用多个接口时经常遇到一个场景:用户快速切换筛选条件,或者组件在请求返回前被卸载。如果每个 then 都顺序执行,旧的请求结果可能会覆盖新状态,或者在组件卸载后触发 setState 报警告。更麻烦的是,有些 Promise 链中间还会写缓存、上报日志、改全局变量,一旦开始执行就很难从外部停下来。原生 Promise 本身没有 cancel 方法,早期 Bluebird 虽然提供过 cancel,但标准方案一直没落地。实际项目中只能靠 AbortController、标志位、或者把链式调用改写成 async 函数配合判断来绕开。这篇文章从一次真实的数据看板翻页问题出发,讲清楚 Promise 链为什么不能直接中断,以及几种在业务代码里可用的方案和它们各自的边界。 看板页面每翻一页会调用三个接口:列表、统计、推荐。代码是这样串起来的: ```js function loadPage(page) { return fetchList(page) .then(list => { state.list = list return fetchStats(page) }) .then(stats => { state.stats = stats return fetchRecommend(page) }) .then(recommend => { state.recommend = recommend }) } ``` 用户从第 1 页快速点到第 5 页时,loadPage(1) 的链不会停,fetchStats(1) 还是会发出去,返回后照样写 state。问题根源不是 fetch 本身,而是 then 回调里的副作用无法被外部撤销。很多人第一反应是给 Promise 加个 wrapper,但包装出来的 cancel 只能阻止后续 then 执行,已经进入微任务队列的回调拦不住,正在飞的网络请求也停不掉。 AbortController 是目前最干净的做法,它本身是给 fetch 设计的,但可以配合标志位用在任何异步链里。改造上面的代码: ```js let controller = null let requestId = 0 async function loadPage(page) { if (controller) controller.abort() controller = new AbortController() const currentId = ++requestId const signal = controller.signal const list = await fetchList(page, { signal }) if (signal.aborted || currentId !== requestId) return state.list = list const stats = await fetchStats(page, { signal }) if (signal.aborted || currentId !== requestId) return state.stats = stats const recommend = await fetchRecommend(page, { signal }) if (signal.aborted || currentId !== requestId) return state.recommend = recommend } ``` 每次调用先把上一次的 controller abort 掉,fetch 会直接抛 AbortError。requestId 是双保险,防止 abort 后旧请求恰好已经 resolve,微任务继续往下跑。注意不要用 try/catch 吞掉 AbortError,否则它会被当成正常业务错误上报。判断 error.name === 'AbortError' 再决定是否忽略。 如果链中间有写缓存或者上报,光靠 abort 还不够。这些副作用不会因为 signal 而自动跳过。得把副作用抽成独立函数,在调用前检查状态: ```js function maybeReport(data, signal) { if (signal.aborted) return report(data) } ``` 另一个容易被忽略的地方是 Promise.all 或 Promise.race。有些代码把多个请求包在一起,然后用一个 then 处理结果。这种结构下 abort 单个请求不会让整个 Promise 立刻 reject,其他请求还会继续。解决办法是给每个 fetch 都传同一个 signal,或者用 Promise.race 和一个 abort 触发的 reject 赛跑: ```js function withAbort(promise, signal) { return Promise.race([ promise, new Promise((_, reject) => { if (signal.aborted) return reject(new DOMException('Aborted', 'AbortError')) signal.addEventListener('abort', () => { reject(new DOMException('Aborted', 'AbortError')) }, { once: true }) }) ]) } ``` React 组件里卸载时取消请求也类似,useEffect 的清理函数里调用 controller.abort()。但要注意,React 18 的 StrictMode 在开发环境会故意 mount-unmount-mount,abort 后第二次请求要能正常发出。上面 requestId 的方案能处理这种情况,因为每次调用都会生成新的 id。 如果项目里全是老式 Promise 链,改动成本高,那就退回到标志位。用一个对象保存当前请求的 token,每个 then 里最先判断 token 是否还是自己: ```js const requestToken = { current: null } function loadPage(page) { const token = { page } requestToken.current = token return fetchList(page) .then(list => { if (requestToken.current !== token) return Promise.reject(new Error('stale')) state.list = list return fetchStats(page) }) .then(stats => { if (requestToken.current !== token) return Promise.reject(new Error('stale')) state.stats = stats }) .catch(err => { if (err.message === 'stale') return throw err }) } ``` 这种写法的缺点是每个 then 都要重复判断,而且 reject 后如果 catch 没写好会污染错误监控。好处是不依赖 fetch 和 AbortController,对任何异步操作都适用,包括 setTimeout 或者第三方 SDK。 选择哪种方式取决于副作用的位置和数量。AbortController 适合网络请求为主的场景,能真正节省带宽。标志位适合异步操作不可取消、但副作用必须跳过的场景。两者也可以混用,AbortController 负责停请求,标志位负责兜底副作用。唯一不能做的是给 Promise 原型加 cancel 方法,那会破坏 thenable 的语义,在 async/await 混用的代码里行为不可预测。 实际改下来,数据看板的翻页请求从原来的 15 个并发降到最多 3 个,旧页码的统计和推荐接口也不会再覆盖新数据。代码里没有用任何特殊的 polyfill,就是 AbortController 加上一个自增 id。 推荐查看天气:https://www.40tianqi.com/jingxingkuangqu/7tian.html 推荐查看天气:https://www.40tianqi.com/jingxingkuangqu/10tian.html 推荐查看天气:https://www.40tianqi.com/jingxingkuangqu/15tian.html 推荐查看天气:https://www.40tianqi.com/jingxingkuangqu/40tian.html 推荐查看天气:https://www.40tianqi.com/jingxing/ 推荐查看天气:https://www.40tianqi.com/jingxing/zuotian.html 推荐查看天气:https://www.40tianqi.com/jingxing/7tian.html 推荐查看天气:https://www.40tianqi.com/jingxing/10tian.html 推荐查看天气:https://www.40tianqi.com/jingxing/15tian.html 推荐查看天气:https://www.40tianqi.com/jingxing/40tian.html 推荐查看天气:https://www.40tianqi.com/zhengding/ 推荐查看天气:https://www.40tianqi.com/zhengding/zuotian.html 推荐查看天气:https://www.40tianqi.com/zhengding/7tian.html 推荐查看天气:https://www.40tianqi.com/zhengding/10tian.html 推荐查看天气:https://www.40tianqi.com/zhengding/15tian.html 推荐查看天气:https://www.40tianqi.com/zhengding/40tian.html 推荐查看天气:https://www.40tianqi.com/luancheng/ 推荐查看天气:https://www.40tianqi.com/luancheng/zuotian.html 推荐查看天气:https://www.40tianqi.com/luancheng/7tian.html 推荐查看天气:https://www.40tianqi.com/luancheng/10tian.html 推荐查看天气:https://www.40tianqi.com/luancheng/15tian.html 推荐查看天气:https://www.40tianqi.com/luancheng/40tian.html 推荐查看天气:https://www.40tianqi.com/xingtang/ 推荐查看天气:https://www.40tianqi.com/xingtang/zuotian.html 推荐查看天气:https://www.40tianqi.com/xingtang/7tian.html 推荐查看天气:https://www.40tianqi.com/xingtang/10tian.html 推荐查看天气:https://www.40tianqi.com/xingtang/15tian.html 推荐查看天气:https://www.40tianqi.com/xingtang/40tian.html 推荐查看天气:https://www.40tianqi.com/lingshou/ 推荐查看天气:https://www.40tianqi.com/lingshou/zuotian.html 推荐查看天气:https://www.40tianqi.com/lingshou/7tian.html 推荐查看天气:https://www.40tianqi.com/lingshou/10tian.html 推荐查看天气:https://www.40tianqi.com/lingshou/15tian.html 推荐查看天气:https://www.40tianqi.com/lingshou/40tian.html 推荐查看天气:https://www.40tianqi.com/gaoyi/ 推荐查看天气:https://www.40tianqi.com/gaoyi/zuotian.html 推荐查看天气:https://www.40tianqi.com/gaoyi/7tian.html 推荐查看天气:https://www.40tianqi.com/gaoyi/10tian.html 推荐查看天气:https://www.40tianqi.com/gaoyi/15tian.html 推荐查看天气:https://www.40tianqi.com/gaoyi/40tian.html 推荐查看天气:https://www.40tianqi.com/shenze/ 推荐查看天气:https://www.40tianqi.com/shenze/zuotian.html 推荐查看天气:https://www.40tianqi.com/shenze/7tian.html 推荐查看天气:https://www.40tianqi.com/shenze/10tian.html 推荐查看天气:https://www.40tianqi.com/shenze/15tian.html 推荐查看天气:https://www.40tianqi.com/shenze/40tian.html 推荐查看天气:https://www.40tianqi.com/zanhuang/ 推荐查看天气:https://www.40tianqi.com/zanhuang/zuotian.html 推荐查看天气:https://www.40tianqi.com/zanhuang/7tian.html 推荐查看天气:https://www.40tianqi.com/zanhuang/10tian.html 推荐查看天气:https://www.40tianqi.com/zanhuang/15tian.html 推荐查看天气:https://www.40tianqi.com/zanhuang/40tian.html 推荐查看天气:https://www.40tianqi.com/wuji/ 推荐查看天气:https://www.40tianqi.com/wuji/zuotian.html 推荐查看天气:https://www.40tianqi.com/wuji/7tian.html 推荐查看天气:https://www.40tianqi.com/wuji/10tian.html 推荐查看天气:https://www.40tianqi.com/wuji/15tian.html 推荐查看天气:https://www.40tianqi.com/wuji/40tian.html 推荐查看天气:https://www.40tianqi.com/shijiazhuangpingshan/ 推荐查看天气:https://www.40tianqi.com/shijiazhuangpingshan/zuotian.html 推荐查看天气:https://www.40tianqi.com/shijiazhuangpingshan/7tian.html 推荐查看天气:https://www.40tianqi.com/shijiazhuangpingshan/10tian.html 推荐查看天气:https://www.40tianqi.com/shijiazhuangpingshan/15tian.html 推荐查看天气:https://www.40tianqi.com/shijiazhuangpingshan/40tian.html 推荐查看天气:https://www.40tianqi.com/yuanshi/ 推荐查看天气:https://www.40tianqi.com/yuanshi/zuotian.html 推荐查看天气:https://www.40tianqi.com/yuanshi/7tian.html 推荐查看天气:https://www.40tianqi.com/yuanshi/10tian.html 推荐查看天气:https://www.40tianqi.com/yuanshi/15tian.html 推荐查看天气:https://www.40tianqi.com/yuanshi/40tian.html 推荐查看天气:https://www.40tianqi.com/zhaoxian/ 推荐查看天气:https://www.40tianqi.com/zhaoxian/zuotian.html 推荐查看天气:https://www.40tianqi.com/zhaoxian/7tian.html 推荐查看天气:https://www.40tianqi.com/zhaoxian/10tian.html 推荐查看天气:https://www.40tianqi.com/zhaoxian/15tian.html 推荐查看天气:https://www.40tianqi.com/zhaoxian/40tian.html 推荐查看天气:https://www.40tianqi.com/xinji/ 推荐查看天气:https://www.40tianqi.com/xinji/zuotian.html 推荐查看天气:https://www.40tianqi.com/xinji/7tian.html 推荐查看天气:https://www.40tianqi.com/xinji/10tian.html 推荐查看天气:https://www.40tianqi.com/xinji/15tian.html 推荐查看天气:https://www.40tianqi.com/xinji/40tian.html 推荐查看天气:https://www.40tianqi.com/shijiazhuangjinzhou/ 推荐查看天气:https://www.40tianqi.com/shijiazhuangjinzhou/zuotian.html 推荐查看天气:https://www.40tianqi.com/shijiazhuangjinzhou/7tian.html 推荐查看天气:https://www.40tianqi.com/shijiazhuangjinzhou/10tian.html 推荐查看天气:https://www.40tianqi.com/shijiazhuangjinzhou/15tian.html 推荐查看天气:https://www.40tianqi.com/shijiazhuangjinzhou/40tian.html 推荐查看天气:https://www.40tianqi.com/xinle/ 推荐查看天气:https://www.40tianqi.com/xinle/zuotian.html 推荐查看天气:https://www.40tianqi.com/xinle/7tian.html 推荐查看天气:https://www.40tianqi.com/xinle/10tian.html 推荐查看天气:https://www.40tianqi.com/xinle/15tian.html 推荐查看天气:https://www.40tianqi.com/xinle/40tian.html 推荐查看天气:https://www.40tianqi.com/shijiazhuangluquan/ 推荐查看天气:https://www.40tianqi.com/shijiazhuangluquan/zuotian.html 推荐查看天气:https://www.40tianqi.com/shijiazhuangluquan/7tian.html 推荐查看天气:https://www.40tianqi.com/shijiazhuangluquan/10tian.html 推荐查看天气:https://www.40tianqi.com/shijiazhuangluquan/15tian.html 推荐查看天气:https://www.40tianqi.com/shijiazhuangluquan/40tian.html 推荐查看天气:https://www.40tianqi.com/tangshan/ 推荐查看天气:https://www.40tianqi.com/tangshan/zuotian.html 推荐查看天气:https://www.40tianqi.com/tangshan/7tian.html 推荐查看天气:https://www.40tianqi.com/tangshan/10tian.html 推荐查看天气:https://www.40tianqi.com/tangshan/15tian.html 推荐查看天气:https://www.40tianqi.com/tangshan/40tian.html 推荐查看天气:https://www.40tianqi.com/lunan/ 推荐查看天气:https://www.40tianqi.com/lunan/zuotian.html 推荐查看天气:https://www.40tianqi.com/lunan/7tian.html 推荐查看天气:https://www.40tianqi.com/lunan/10tian.html 推荐查看天气:https://www.40tianqi.com/lunan/15tian.html 推荐查看天气:https://www.40tianqi.com/lunan/40tian.html 推荐查看天气:https://www.40tianqi.com/lubei/ 推荐查看天气:https://www.40tianqi.com/lubei/zuotian.html 推荐查看天气:https://www.40tianqi.com/lubei/7tian.html 推荐查看天气:https://www.40tianqi.com/lubei/10tian.html 推荐查看天气:https://www.40tianqi.com/lubei/15tian.html 推荐查看天气:https://www.40tianqi.com/lubei/40tian.html 推荐查看天气:https://www.40tianqi.com/guye/ 推荐查看天气:https://www.40tianqi.com/guye/zuotian.html 推荐查看天气:https://www.40tianqi.com/guye/7tian.html 推荐查看天气:https://www.40tianqi.com/guye/10tian.html 推荐查看天气:https://www.40tianqi.com/guye/15tian.html 推荐查看天气:https://www.40tianqi.com/guye/40tian.html 推荐查看天气:https://www.40tianqi.com/fengnan/ 推荐查看天气:https://www.40tianqi.com/fengnan/zuotian.html 推荐查看天气:https://www.40tianqi.com/fengnan/7tian.html 推荐查看天气:https://www.40tianqi.com/fengnan/10tian.html 推荐查看天气:https://www.40tianqi.com/fengnan/15tian.html 推荐查看天气:https://www.40tianqi.com/fengnan/40tian.html 推荐查看天气:https://www.40tianqi.com/fengrun/ 推荐查看天气:https://www.40tianqi.com/fengrun/zuotian.html 推荐查看天气:https://www.40tianqi.com/fengrun/7tian.html 推荐查看天气:https://www.40tianqi.com/fengrun/10tian.html 推荐查看天气:https://www.40tianqi.com/fengrun/15tian.html 推荐查看天气:https://www.40tianqi.com/fengrun/40tian.html 推荐查看天气:https://www.40tianqi.com/luanxian/ 推荐查看天气:https://www.40tianqi.com/luanxian/zuotian.html 推荐查看天气:https://www.40tianqi.com/luanxian/7tian.html 推荐查看天气:https://www.40tianqi.com/luanxian/10tian.html 推荐查看天气:https://www.40tianqi.com/luanxian/15tian.html 推荐查看天气:https://www.40tianqi.com/luanxian/40tian.html 推荐查看天气:https://www.40tianqi.com/luannan/ 推荐查看天气:https://www.40tianqi.com/luannan/zuotian.html 推荐查看天气:https://www.40tianqi.com/luannan/7tian.html 推荐查看天气:https://www.40tianqi.com/luannan/10tian.html 推荐查看天气:https://www.40tianqi.com/luannan/15tian.html 推荐查看天气:https://www.40tianqi.com/luannan/40tian.html 推荐查看天气:https://www.40tianqi.com/leting/ 推荐查看天气:https://www.40tianqi.com/leting/zuotian.html 推荐查看天气:https://www.40tianqi.com/leting/7tian.html 推荐查看天气:https://www.40tianqi.com/leting/10tian.html 推荐查看天气:https://www.40tianqi.com/leting/15tian.html 推荐查看天气:https://www.40tianqi.com/leting/40tian.html 推荐查看天气:https://www.40tianqi.com/tangshanqianxi/ 推荐查看天气:https://www.40tianqi.com/tangshanqianxi/zuotian.html 推荐查看天气:https://www.40tianqi.com/tangshanqianxi/7tian.html 推荐查看天气:https://www.40tianqi.com/tangshanqianxi/10tian.html 推荐查看天气:https://www.40tianqi.com/tangshanqianxi/15tian.html 推荐查看天气:https://www.40tianqi.com/tangshanqianxi/40tian.html 推荐查看天气:https://www.40tianqi.com/tangshanyutian/ 推荐查看天气:https://www.40tianqi.com/tangshanyutian/zuotian.html 推荐查看天气:https://www.40tianqi.com/tangshanyutian/7tian.html 推荐查看天气:https://www.40tianqi.com/tangshanyutian/10tian.html 推荐查看天气:https://www.40tianqi.com/tangshanyutian/15tian.html 推荐查看天气:https://www.40tianqi.com/tangshanyutian/40tian.html 推荐查看天气:https://www.40tianqi.com/zunhua/ 推荐查看天气:https://www.40tianqi.com/zunhua/zuotian.html 推荐查看天气:https://www.40tianqi.com/zunhua/7tian.html 推荐查看天气:https://www.40tianqi.com/zunhua/10tian.html 推荐查看天气:https://www.40tianqi.com/zunhua/15tian.html 推荐查看天气:https://www.40tianqi.com/zunhua/40tian.html 推荐查看天气:https://www.40tianqi.com/tangshanqianan/ 推荐查看天气:https://www.40tianqi.com/tangshanqianan/zuotian.html 推荐查看天气:https://www.40tianqi.com/tangshanqianan/7tian.html 推荐查看天气:https://www.40tianqi.com/tangshanqianan/10tian.html 推荐查看天气:https://www.40tianqi.com/tangshanqianan/15tian.html 推荐查看天气:https://www.40tianqi.com/tangshanqianan/40tian.html 推荐查看天气:https://www.40tianqi.com/qinhuangdao/ 推荐查看天气:https://www.40tianqi.com/qinhuangdao/zuotian.html 推荐查看天气:https://www.40tianqi.com/qinhuangdao/7tian.html 推荐查看天气:https://www.40tianqi.com/qinhuangdao/10tian.html 推荐查看天气:https://www.40tianqi.com/qinhuangdao/15tian.html 推荐查看天气:https://www.40tianqi.com/qinhuangdao/40tian.html 推荐查看天气:https://www.40tianqi.com/haigang/ 推荐查看天气:https://www.40tianqi.com/haigang/zuotian.html 推荐查看天气:https://www.40tianqi.com/haigang/7tian.html 推荐查看天气:https://www.40tianqi.com/haigang/10tian.html 推荐查看天气:https://www.40tianqi.com/haigang/15tian.html 推荐查看天气:https://www.40tianqi.com/haigang/40tian.html 推荐查看天气:https://www.40tianqi.com/shanhaiguan/ 推荐查看天气:https://www.40tianqi.com/shanhaiguan/zuotian.html 推荐查看天气:https://www.40tianqi.com/shanhaiguan/7tian.html 推荐查看天气:https://www.40tianqi.com/shanhaiguan/10tian.html 推荐查看天气:https://www.40tianqi.com/shanhaiguan/15tian.html 推荐查看天气:https://www.40tianqi.com/shanhaiguan/40tian.html 推荐查看天气:https://www.40tianqi.com/beidaihe/ 推荐查看天气:https://www.40tianqi.com/beidaihe/zuotian.html 推荐查看天气:https://www.40tianqi.com/beidaihe/7tian.html 推荐查看天气:https://www.40tianqi.com/beidaihe/10tian.html

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册