处理多个异步任务
掌握协调多个独立或相互依赖的异步任务,确保所有操作按正确顺序执行并妥善处理错误。
处理多个异步任务 是 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 反馈 — 无需本地设置。
此课程中的所有课时
- 理解 Deferred 对象
- 串联与组合 Promise
- 处理多个异步任务