利用缓存与延迟对象
使用选择器缓存避免重复查询 DOM,并理解 jQuery Deferred 对象,以更高效地管理异步操作,提升代码可读性和性能。
利用缓存与延迟对象 是 CoddyKit 上的免费 jQuery Academy 课时。 这是第 3 节课,共 3 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 jQuery Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 jQuery Academy 课程共包含 3 节课。
使用缓存和 Deferred 提升性能
欢迎!在本课中,我们将探索两种让 jQuery 应用更快、更高效的强大技术:选择器缓存和 Deferred 对象。
这些方法可以帮助您减少重复工作,并轻松管理复杂的异步操作。
选择器缓存为何重要
每次使用类似 $("#myElement") 或 $(".item") 的 jQuery 选择器时,jQuery 都必须遍历文档对象模型(DOM)来查找匹配的元素。
- 这种遍历可能很慢,尤其是在选择器复杂或 DOM 树很大的情况下。
- 反复查找相同元素会浪费处理能力。
缓存可以帮助我们避免这些问题!
存储您的选择结果
不要多次搜索 DOM,而是将 jQuery 选择的结果存储在变量中。这个变量随后会保存对 jQuery 对象的引用。
请运行下面的示例,看看我们如何缓存选择结果:
// Imagine this is in your HTML
// <div id="myDiv">Hello</div>
// Simulate jQuery selecting an element
// In a real browser, this would return a jQuery object
const $myElement = {
id: "myDiv",
text: "Hello",
// Simulate jQuery methods
css: function(prop, value) {
console.log(`Setting ${prop} to ${value} on #${this.id}`);
},
addClass: function(cls) {
console.log(`Adding class "${cls}" to #${this.id}`);
}
};
console.log("--- Without Caching (simulated) ---");
// This would ideally re-query the DOM
$myElement.css("color", "blue"); // Simulates $("#myDiv").css(...)
$myElement.addClass("highlight"); // Simulates $("#myDiv").addClass(...)
console.log("\n--- With Caching ---");
// We already have $myElement, so no re-query
$myElement.css("font-weight", "bold");
$myElement.addClass("active");通过链式调用提高效率
jQuery 的方法链式调用本身就是一种提高效率的方式,因为它会针对同一组已选元素进行操作。
但是,当您需要在代码的不同位置或不同事件处理函数中对相同元素执行操作时,缓存就非常重要。
// Chaining is good for sequential ops
$("#myElement")
.addClass("active")
.css("color", "blue")
.fadeIn();
// Caching is better for repeated, non-sequential ops
const $cachedElement = $("#myElement");
// Later in code...
$cachedElement.trigger("click");
// Even later...
$cachedElement.removeClass("active");重复使用选择结果
设想这样一种场景:您经常需要与一组元素交互。缓存最初的选择结果可以避免重复查询 DOM。
这在循环、事件处理函数或对同一组元素执行操作的函数中尤其有用。
// Imagine HTML: <li class="item">1</li> <li class="item">2</li>
// <li class="item">3</li> <button id="toggleBtn">Toggle</button>
// Simulate jQuery context
const $items = [{
text: "Item 1"
}, {
text: "Item 2"
}];
const $toggleButton = {
text: "Toggle Button"
};
console.log("Cached items count:", $items.length);
console.log("Cached button text:", $toggleButton.text);
// Later, you might need them again, without re-querying
// e.g., in an event handler
function handleToggle() {
// Use $items and $toggleButton directly
console.log("Toggle button clicked! Working with cached items.");
}
// Call the function
handleToggle();管理异步操作
jQuery 中的 Deferred 对象提供了一种方式,用于将多个回调函数注册到队列中、调用回调队列,并传递任何同步或异步操作的成功或失败状态。
- 您可以把它想象成对未来结果的“promise”。
- 它有助于组织处理 AJAX 请求、动画或计时器等操作的代码。
创建新的 Deferred
您可以使用 $.Deferred() 创建新的 Deferred 对象。该对象提供了用于控制其状态的方法:成功时使用 resolve(),失败时使用 reject()。
让我们看看如何设置一个在延迟后完成的基本 Deferred。
function doSomethingAsync() {
const dfd = $.Deferred(); // Create a new Deferred
setTimeout(function() {
const success = Math.random() > 0.5; // Simulate success/failure
if (success) {
dfd.resolve("Operation successful!"); // Resolve on success
} else {
dfd.reject("Operation failed!"); // Reject on failure
}
}, 1000); // Simulate 1-second delay
return dfd.promise(); // Return the Promise part
}
// This code will run when the scene loads
// We'll attach handlers in the next scene
console.log("Deferred created. Waiting for resolution...");使用 .done() 和 .fail()
获得 Deferred 对象(或其 promise)后,您可以使用 .done() 处理成功情况,使用 .fail() 处理错误情况,从而附加回调函数。
无论成功还是失败,.always() 回调都会运行。
function doSomethingAsync() {
const dfd = $.Deferred();
setTimeout(function() {
const success = true; // For this example, let's ensure success
if (success) {
dfd.resolve("Data loaded!");
} else {
dfd.reject("Network error!");
}
}, 500);
return dfd.promise();
}
const myPromise = doSomethingAsync();
myPromise.done(function(message) {
console.log("SUCCESS:", message);
});
myPromise.fail(function(errorMessage) {
console.log("FAILED:", errorMessage);
});
myPromise.always(function() {
console.log("Operation complete (done or failed).");
});
console.log("Initiating async operation...");使用 .then() 转换结果
.done() 和 .fail() 用于最终处理,而 .then() 更加灵活。它可以转换已 resolve 的值,甚至返回一个新的 promise,从而实现顺序处理。
您可以使用 .then() 处理结果,然后再将结果传递下去。
function fetchData() {
const dfd = $.Deferred();
setTimeout(() => {
console.log("Data fetched.");
dfd.resolve({
id: 1,
name: "Widget"
});
}, 500);
return dfd.promise();
}
fetchData()
.then(function(data) {
console.log("Processing fetched data:", data);
return data.name.toUpperCase(); // Transform the data
})
.then(function(processedName) {
console.log("Transformed name:", processedName);
// This second .then() receives the result of the first .then()
})
.fail(function(error) {
console.error("Error:", error);
});
console.log("Starting data fetch and transformation...");缓存与 Deferred 测验
准备好接受一个小挑战了吗?测试一下您对选择器缓存和 Deferred 对象的理解。
总结:更快、更智能的 jQuery
做得很好!您已经学会了如何显著提升 jQuery 应用的性能并改善代码组织:
- 选择器缓存:将 jQuery 选择结果存储在变量中,避免代价高昂的重复 DOM 查找。
- Deferred 对象:使用
$.Deferred()、.resolve()、.reject()、.done()、.fail()和.then(),以清晰高效的方式管理复杂的异步操作。
应用这些技术,构建更可靠、性能更好的 Web 应用!
常见问题解答
「利用缓存与延迟对象」课时是免费的吗?
是的 — 「利用缓存与延迟对象」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 jQuery Academy 课程的其余内容,请升级到 CoddyKit PRO。 jQuery Academy 课程共包含 3 节课。
「利用缓存与延迟对象」这节课中我会学到什么?
使用选择器缓存避免重复查询 DOM,并理解 jQuery Deferred 对象,以更高效地管理异步操作,提升代码可读性和性能。 你通过在浏览器中直接运行的动手代码来练习 jQuery Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 jQuery Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 jQuery Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 3 节。
「利用缓存与延迟对象」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 jQuery Academy 课中编写并运行代码吗?
能。每节 jQuery Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。