0Pricing
jQuery Academy · 课时

处理多个异步任务

掌握协调多个独立或相互依赖的异步任务,确保所有操作按正确顺序执行并妥善处理错误。

处理多个异步任务 是 CoddyKit 上的免费 jQuery Academy 课时。 这是第 3 节课,共 3 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 jQuery Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 jQuery Academy 课程共包含 3 节课。

为什么要协调异步任务?

在 Web 开发中,许多操作都是异步的。这意味着它们不会立即发生,也不一定按照严格顺序发生。比如从服务器获取数据、加载图片或运行动画。

当应用需要同时执行多个此类任务,或需要按照特定顺序执行时,就需要一种有效协调这些任务的方法。本课将向您展示如何做到这一点!

多个任务带来的挑战

假设您需要加载用户的个人资料和最新通知。这两项分别对应独立的服务器请求。

  • 您如何知道两者都已完成?
  • 如果其中一个失败了怎么办?
  • 如果一个任务依赖另一个任务怎么办(例如,获取个人资料中找到的特定用户 ID 对应的通知)?

如果没有适当的协调,界面可能会显示不完整的数据,甚至完全无法正常运行。

使用 `$.when()` 实现并行

jQuery 的 $.when() 是协调多个相互独立的异步操作的强大工具。它接受一个或多个 Deferred/Promise 对象作为参数。

$.when() 返回一个主 Promise,只有在传入的所有单独 Promise 都得到解决后才会得到解决。如果其中任何一个被拒绝,主 Promise 会立即被拒绝。

`$.when()` 示例:并行获取

下面我们模拟并行获取两组不同的数据。为便于演示,我们将使用 $.Deferred() 来模拟 AJAX 请求。

请尝试运行以下代码:

// Assume jQuery is loaded in the environment
$(function() {
  function fetchData(name, delay) {
    let dfd = $.Deferred();
    setTimeout(function() {
      console.log(`Finished fetching ${name}`);
      dfd.resolve(`Data for ${name}`);
    }, delay);
    return dfd.promise();
  }

  let profilePromise = fetchData("User Profile", 1500);
  let settingsPromise = fetchData("App Settings", 800);

  console.log("Starting parallel fetches...");

  $.when(profilePromise, settingsPromise)
    .done(function(profileData, settingsData) {
      console.log("All data loaded successfully!");
      console.log(`Profile: ${profileData}`);
      console.log(`Settings: ${settingsData}`);
    });
});

处理 `$.when()` 的结果

当 $.when() 返回的 Promise 得到解决时,其 .done() 回调会将每个原始 Promise 的已解决值作为单独的参数接收。

  • 如果向 $.when() 传入 N 个 Promise,.done() 回调就会接收 N 个参数。
  • 参数顺序与 Promise 传入 $.when() 的顺序相同。

这样,所有结果准备就绪后,就可以轻松处理这些结果。

`$.when()` 错误处理

如果某个并行操作失败,会发生什么?只要任意一个单独的 Promise 被拒绝,$.when() 的主 Promise 就会立即被拒绝。

随后会触发 .fail() 回调,并接收第一个失败的 Promise 提供的拒绝原因。其余并行操作仍会完成,但 $.when() 已经发出了失败信号。

示例:`$.when()` 处理失败

让我们修改前面的示例,使其中一个获取操作失败。请观察输出结果:

// Assume jQuery is loaded in the environment
$(function() {
  function fetchData(name, delay, shouldSucceed = true) {
    let dfd = $.Deferred();
    setTimeout(function() {
      if (shouldSucceed) {
        console.log(`Finished fetching ${name}`);
        dfd.resolve(`Data for ${name}`);
      } else {
        console.log(`Failed to fetch ${name}`);
        dfd.reject(`Error: ${name} could not be loaded`);
      }
    }, delay);
    return dfd.promise();
  }

  let profilePromise = fetchData("User Profile", 1500, true);
  let settingsPromise = fetchData("App Settings", 800, false); // This one will fail

  console.log("Starting parallel fetches (one will fail)...");

  $.when(profilePromise, settingsPromise)
    .done(function(profileData, settingsData) {
      console.log("All data loaded successfully! (This won't run)");
    })
    .fail(function(errorReason) {
      console.log("One or more operations failed!");
      console.log(`Reason: ${errorReason}`);
    });
});

协调具有依赖关系的任务

有时,任务之间并不是相互独立的。您可能需要:

  • 获取用户 ID。
  • 然后使用该 ID 获取用户详细信息。
  • 接着使用这些详细信息获取用户的特定帖子。

这要求将异步操作按顺序链接起来,其中每一步都依赖于前一步的成功及其结果。我们可以通过链接 .then() 或 .pipe() 来实现这一点。

示例:链接具有依赖关系的 AJAX 请求

下面展示如何链接两个模拟的 AJAX 调用,其中第二个调用依赖于第一个调用的结果。请注意,第一个 .then() 的返回值会成为下一个 .then() 的输入。

// Assume jQuery is loaded in the environment
$(function() {
  function fetchUserId() {
    let dfd = $.Deferred();
    setTimeout(() => {
      console.log("User ID fetched: 123");
      dfd.resolve(123);
    }, 500);
    return dfd.promise();
  }

  function fetchUserDetails(userId) {
    let dfd = $.Deferred();
    setTimeout(() => {
      if (userId === 123) {
        console.log(`Details fetched for user ${userId}`);
        dfd.resolve(`Details for User ${userId}`);
      } else {
        dfd.reject("Invalid User ID");
      }
    }, 700);
    return dfd.promise();
  }

  console.log("Starting dependent fetch chain...");

  fetchUserId()
    .then(function(id) {
      return fetchUserDetails(id); // Return a new promise
    })
    .done(function(details) {
      console.log("Full chain successful!");
      console.log(`Final Result: ${details}`);
    })
    .fail(function(error) {
      console.log("Chain failed:", error);
    });
});

检查您的知识掌握情况

请考虑这样一种情况:您想要加载用户的个人资料和好友列表。好友列表请求需要用户 ID,而该 ID 包含在个人资料数据中。

哪种 jQuery 方法最适合处理这种特定的协调需求?

回顾:掌握异步协调

您已经学会了如何有效处理多个异步任务!

  • $.when():适合并行运行相互独立的任务,并等待所有任务完成或任一任务失败。
  • 使用 .then() 进行链接:非常适合处理具有依赖关系的任务,即一个操作的输出是下一个操作所需的输入。
  • 错误处理:$.when() 和链接的 Promise 都提供了 .fail(),可在任意环节捕获拒绝,从而让应用更加可靠。

这些模式对于使用 jQuery 构建动态且响应迅速的 Web 应用至关重要。

常见问题解答

「处理多个异步任务」课时是免费的吗?

是的 — 「处理多个异步任务」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 jQuery Academy 课程的其余内容,请升级到 CoddyKit PRO。 jQuery Academy 课程共包含 3 节课。

「处理多个异步任务」这节课中我会学到什么?

掌握协调多个独立或相互依赖的异步任务,确保所有操作按正确顺序执行并妥善处理错误。 你通过在浏览器中直接运行的动手代码来练习 jQuery Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 jQuery Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 jQuery Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 3 节。

「处理多个异步任务」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 jQuery Academy 课中编写并运行代码吗?

能。每节 jQuery Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 理解 Deferred 对象
  2. 串联与组合 Promise
  3. 处理多个异步任务
← 返回 jQuery Academy