EP072. “用 $.when().then() 重构成并行请求 + 错误处理”
🔒 登录后可标记已读接着上一讲的「嵌套请求能跑但效率不好」的问题,这一讲把两个 $.getJSON() 请求从「一个套一个」的写法重构成 $.when(请求1, 请求2).then(成功回调, 失败回调),让两个请求同时(异步)发出去,等两个都有响应了才继续往下处理,视觉上会比嵌套写法快一些。顺便加上错误处理:如果请求过程中出问题(网络问题、网址拼错等),页面会显示「Unexpected error; please try again.」,而不是让脚本直接报错崩掉。
涉及文件
wp-content/themes/fictional-university-theme/src/modules/Search.js(修改,getResults()从嵌套$.getJSON()重写成$.when().then())
代码实现
// wp-content/themes/fictional-university-theme/src/modules/Search.js
// 修改:getResults() 从嵌套请求改成 $.when().then() 并行请求 + 错误处理
getResults() {
$.when(
$.getJSON(universityData.root_url + "/wp-json/wp/v2/posts?search=" + this.searchField.val()),
$.getJSON(universityData.root_url + "/wp-json/wp/v2/pages?search=" + this.searchField.val())
).then(
(posts, pages) => {
var combinedResults = posts[0].concat(pages[0])
this.resultsDiv.html(`
<h2 class="search-overlay__section-title">General Information</h2>
${combinedResults.length ? '<ul class="link-list min-list">' : "<p>No general information matches that search.</p>"}
${combinedResults.map(item => `<li><a href="${item.link}">${item.title.rendered}</a></li>`).join("")}
${combinedResults.length ? "</ul>" : ""}
`)
this.isSpinnerVisible = false
},
() => {
this.resultsDiv.html("<p>Unexpected error; please try again.</p>")
}
)
}
要点:
$.when(请求A, 请求B):括号里可以塞任意多个$.getJSON()请求,它们会同时发出去(异步、互不等待),$.when()负责在背后"看管"这些请求,等全部都有结果了才会继续走到.then()。- 因为
$.when()已经在背后处理好每个请求的结果,这里的$.getJSON()只需要传一个参数(网址),不再需要各自的回调函数(回调函数交给外层的.then()统一处理)。 .then(成功回调, 失败回调):第一个函数参数是全部请求都成功时执行的,参数名(这里叫posts、pages)会按请求在$.when()里的顺序自动对应;第二个函数参数是只要有请求失败(网络问题、404 等)就会执行的错误处理函数。posts[0]/pages[0]:因为经过$.when().then()包装后,传进来的每个参数不再是纯粹的 JSON 数据,而是 jQuery 内部的一个数组,第0项才是真正的响应数据(JSON 本身),第1、2项是这次请求的状态信息(比如 "success" 字样等)。所以合并结果那行必须写成posts[0].concat(pages[0]),直接写posts.concat(pages)(EP071 遗留的旧写法)在这里已经不对了,是这一讲跟着改掉的地方之一。- 错误回调里直接把
resultsDiv的内容换成一段提示文字<p>Unexpected error; please try again.</p>,让脚本在请求失败时不会白屏或者控制台报一堆红字却什么都不告诉用户。
Hook / Function 速查
| 名称 | 类型 | 用途 |
|---|---|---|
$.when(请求1, 请求2, ...) | jQuery 方法 | 同时管理多个异步请求(如多个 $.getJSON()),全部完成后才继续 |
.then(成功回调, 失败回调) | jQuery Promise 方法 | 配合 $.when() 使用;第一个函数在全部请求成功时执行,第二个函数在任一请求失败时执行 |
jqXHR 数组的 [0] | jQuery 内部数据结构 | $.when().then() 里每个请求参数其实是一个数组,[0] 才是真正的响应数据本身 |
常见坑
- 从嵌套写法迁移过来时容易漏改:
$.when().then()里拿到的posts、pages参数已经不是纯 JSON 数据了,而是多了状态信息包在外层的数组,如果还沿用 EP071 的posts.concat(pages),合并出来的结果会不对,必须改成posts[0].concat(pages[0])。 .then()如果只传一个函数参数,那就只是"成功回调",遇到请求失败(网络断线、URL 拼错等)脚本会直接报错卡住,用户什么提示都看不到;要加错误处理必须显式传入第二个函数参数。
延伸 / 后续讲座会用到
transcript 结尾提到下一讲会继续深入学习 WordPress REST API 的自定义用法(比如超出内建 posts/pages 之外的其他文章类型)。
Sources
Udemy:
- Become a WordPress Developer: Unlocking Power With Code — Section 14, EP072