串联与组合 Promise
学习使用 .then() 和 .pipe() 串联多个异步操作,并通过 $.when() 等待多个 Promise 完成,以组合复杂的工作流。
串联与组合 Promise 是 CoddyKit 上的免费 jQuery Academy 课时。 这是第 2 节课,共 3 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 jQuery Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 jQuery Academy 课程共包含 3 节课。
按顺序执行异步操作
在 Web 开发中,我们经常需要按照特定顺序执行异步任务(例如获取数据)。链接 Promise 可以让我们整洁地完成这项工作。
回调嵌套容易导致“回调地狱”,而我们可以改为按顺序连接各个操作,使代码更易于阅读和维护。
使用 .then() 进行链接
.then() 方法是实现链接的基础。当 Deferred(或 Promise)得到解决时,其 .then() 回调会执行。该回调返回的内容随后可以供链接中的下一个 .then() 使用。
如果回调返回一个新的 Deferred,链接会等待这个新的 Deferred 得到解决后再继续。
简单的 .then() 链示例
下面来看一个简单示例,其中我们模拟两个异步步骤。第二个步骤仅在第一个步骤完成后运行,并且会使用第一个步骤中的数据。
请注意,step1 的结果('Data from Step 1')会传递给 step2。
function runChainExample() {
let dfd1 = new $.Deferred();
let dfd2 = new $.Deferred();
setTimeout(() => {
console.log("Step 1 complete!");
dfd1.resolve("Data from Step 1");
}, 500);
dfd1.then(function(data1) {
console.log("Received in Step 2: " + data1);
setTimeout(() => {
console.log("Step 2 complete!");
dfd2.resolve("Processed " + data1);
}, 300);
return dfd2;
}).then(function(data2) {
console.log("Received in Final Step: " + data2);
console.log("Chain finished!");
});
}
$(document).ready(function() {
runChainExample();
});.then() 链中的数据流
.then() 回调返回的值决定了下一个 .then() 的输入。
- 如果返回非 Deferred 值,该值就会成为下一个
.then()的已解决值。 - 如果返回一个 Deferred 对象,链接会暂停,直到该 Deferred 得到解决,然后将其已解决的值传递给下一个
.then()。
使用 .pipe() 进行转换
虽然 .then() 是现代标准,但 jQuery 的 .Deferred() 也提供了 .pipe()。它与 .then() 类似,但最初设计用于转换已解决值或已拒绝值,或者筛选出继续执行链接的 Deferred。
.pipe() 可以返回一个新的 Deferred,该 Deferred 会以转换后的值得到解决,从而有效地将该值“传输”到下一个阶段。
.pipe() 转换示例
在这里,我们使用 .pipe() 获取第一个操作的结果,将其转换(例如转换为大写),然后把转换后的值传递给最终的 .done() 处理程序。
function runPipeExample() {
let dfd = new $.Deferred();
setTimeout(() => {
console.log("Initial data ready.");
dfd.resolve("hello world");
}, 500);
dfd.pipe(function(originalData) {
console.log("Piping: Transforming data...");
return originalData.toUpperCase(); // Transforms the value
}).done(function(transformedData) {
console.log("Final result: " + transformedData);
});
}
$(document).ready(function() {
runPipeExample();
});使用 $.when() 进行组合
如果您有多个相互独立的异步任务,但需要等待所有任务完成后才能继续,该怎么办?这正是 $.when() 的用武之地。
$.when() 接受一个或多个 Deferred 对象(或 Promise)作为参数,并返回一个新的 Deferred。只有当所有输入 Deferred 都得到解决时,这个新的 Deferred 才会得到解决。
$.when() 并行任务示例
在本示例中,我们模拟两个相互独立的 AJAX 请求(fetchUser 和 fetchPosts)。我们使用 $.when() 等待两者完成,然后记录组合后的结果。
请注意,它们是并行运行的,而不是按顺序运行。
function runWhenExample() {
function fetchUser() {
let dfd = new $.Deferred();
setTimeout(() => {
console.log("User data fetched.");
dfd.resolve({ id: 1, name: "Alice" });
}, 800);
return dfd.promise();
}
function fetchPosts() {
let dfd = new $.Deferred();
setTimeout(() => {
console.log("Posts data fetched.");
dfd.resolve([{ id: 101, title: "Post 1" }, { id: 102, title: "Post 2" }]);
}, 500);
return dfd.promise();
}
$.when(fetchUser(), fetchPosts())
.done(function(userData, postsData) {
console.log("All data loaded!");
console.log("User: ", userData);
console.log("Posts: ", postsData);
})
.fail(function() {
console.log("One or more tasks failed.");
});
}
$(document).ready(function() {
runWhenExample();
});访问 $.when() 的结果
当 $.when() 返回的 Deferred 得到解决时,其 .done() 或 .then() 回调会按照输入 Deferred 传入 $.when() 的顺序,以单独的参数接收各个输入 Deferred 的已解决值。
这样一来,所有数据都可用后,就能轻松组合并处理来自多个来源的数据。
Promise 链测验
请考虑以下 jQuery 代码片段:
let dfd1 = new $.Deferred();
let dfd2 = new $.Deferred();
dfd1.then(function(val) {
return val + " World";
}).then(function(newVal) {
console.log(newVal); // Line A
return dfd2;
}).then(function() {
console.log("Finished!"); // Line B
});
dfd1.resolve("Hello");
dfd2.resolve();控制台最终会输出什么内容,输出顺序又是怎样的?
回顾:链接与组合
我们已经学习了如何管理复杂的异步工作流:
- 使用
.then()进行链接:按顺序执行操作,将结果从一个阶段传递到下一个阶段。 .pipe():一种较早的方法,用于在链接中转换值或映射 Deferred。- 使用
$.when()进行组合:等待多个相互独立的 Deferred 并行完成后再继续,并将它们的结果作为单独的参数提供。
这些模式对于构建可靠且易读的异步应用至关重要。
常见问题解答
「串联与组合 Promise」课时是免费的吗?
是的 — 「串联与组合 Promise」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 jQuery Academy 课程的其余内容,请升级到 CoddyKit PRO。 jQuery Academy 课程共包含 3 节课。
「串联与组合 Promise」这节课中我会学到什么?
学习使用 .then() 和 .pipe() 串联多个异步操作,并通过 $.when() 等待多个 Promise 完成,以组合复杂的工作流。 你通过在浏览器中直接运行的动手代码来练习 jQuery Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 jQuery Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 jQuery Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 3 节。
「串联与组合 Promise」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 jQuery Academy 课中编写并运行代码吗?
能。每节 jQuery Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 理解 Deferred 对象
- 串联与组合 Promise
- 处理多个异步任务