CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
JavaScript 进阶/课时/综合练习
RawBlame
课时目录12 节

JavaScript 进阶

  1. 01JS 进阶地图
  2. 02变量与提升
  3. 03运算符与相等
  4. 04控制流深入
  5. 05函数与 this
  6. 06异步深入
  7. 07对象与原型
  8. 08集合与 JSON
  9. 09模块系统
  10. 10内存与 GC
  11. 11调试与异常
  12. 12综合练习

综合练习

用 Promise + fetch 重构一段回调代码。

40 分钟

综合练习

本课串联 javascript-core 与本 track 所学:用 Promise + fetch 重构一段回调风格代码,并加入错误处理、并发与模块划分。完成后可继续 nodejs-essentials 服务端实践或 react-essentials 界面集成。

学习目标

  • 将嵌套回调改写为 Promise 链或 async/await
  • 用 Promise.all 并发请求多个 API
  • 按 ESM 拆分 api / ui 模块

需求说明

实现「课程 track 详情页」数据加载:先取 track 元信息,再并行取 lessons 列表与 roadmap 节点,最后合并展示。

起始代码(回调风格,待重构)

function loadTrackPage(slug, onDone, onError) {
  fetch('/api/tracks/' + slug, function (err, trackRes) {
    if (err) return onError(err);
    parseJson(trackRes, function (err2, track) {
      if (err2) return onError(err2);
      fetch('/api/tracks/' + slug + '/lessons', function (err3, lessonsRes) {
        if (err3) return onError(err3);
        parseJson(lessonsRes, function (err4, lessons) {
          if (err4) return onError(err4);
          fetch('/api/roadmaps/javascript', function (err5, mapRes) {
            if (err5) return onError(err5);
            parseJson(mapRes, function (err6, roadmap) {
              if (err6) return onError(err6);
              onDone({ track, lessons, roadmap });
            });
          });
        });
      });
    });
  });
}

参考答案结构

// api/http.js
export async function getJson(url, options = {}) {
  const res = await fetch(url, options);
  if (!res.ok) {
    throw new Error(`HTTP ${res.status}: ${url}`);
  }
  return res.json();
}

// api/trackPage.js
import { getJson } from './http.js';

export async function loadTrackPage(slug) {
  const track = await getJson(`/api/tracks/${slug}`);
  const [lessons, roadmap] = await Promise.all([
    getJson(`/api/tracks/${slug}/lessons`),
    getJson('/api/roadmaps/javascript'),
  ]);
  return { track, lessons, roadmap };
}

// main.js
import { loadTrackPage } from './api/trackPage.js';

async function main() {
  try {
    const data = await loadTrackPage('javascript-advanced-essentials');
    render(data);
  } catch (e) {
    showError(e.message);
  }
}

加分项

// 超时 + 取消
export async function getJson(url, { signal, timeoutMs = 8000 } = {}) {
  const controller = new AbortController();
  const timer = setTimeout(() => controller.abort(), timeoutMs);
  const combined = signal
    ? AbortSignal.any([signal, controller.signal])
    : controller.signal;

  try {
    const res = await fetch(url, { signal: combined });
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    return await res.json();
  } finally {
    clearTimeout(timer);
  }
}

用 Map 缓存已加载 slug,避免重复请求(注意失效策略)。

自测清单

  • 无三层以上嵌套回调
  • 404 / 网络错误有明确提示
  • lessons 与 roadmap 并行加载
  • 模块文件职责单一(http / trackPage / render)

练习

  • 完整实现 loadTrackPage 并在 Console 或 Node 跑通(可 mock fetch)
  • 故意让 lessons API 失败,验证 catch 与 UI 降级
  • 写单元测试:mock fetch 返回固定 JSON,断言合并结果

小结

回调 → async/await + 模块拆分 + 并发与错误处理,是进阶 JS 的实战闭环。 恭喜完成 JavaScript 进阶 track。

加载本节练习…
← 上一课调试与异常