EP071. “扩展成多文章类型搜索(posts + pages 嵌套请求版)”
🔒 登录后可标记已读📌 本讲代码没有对应的 -end 代码快照可核对:EP072 会立刻把这一讲写的嵌套 $.getJSON() 写法重构成 $.when().then() 并行版本,course 提供的 zip 资源直接跳到了 EP072 重构后的版本(54-end),中间这一版没有单独打包。下面的代码是完全根据 transcript 里讲师口述的操作步骤(剪切/粘贴/改名的具体动作)逐句复原的,不是对照代码快照核实过的,使用时请以理解思路为主,实际要抄的代码建议直接抄 EP072 那版。
之前的搜索只查 posts 一种文章类型,所以像「about us」这种页面(page)内容的关键词搜不到。这一讲让搜索同时覆盖 posts 和 pages 两种类型:在第一个 $.getJSON() 请求的回调里面,再嵌套发第二个 $.getJSON() 请求去查 pages,等第二个也回来后用 Array.prototype.concat() 把两个结果数组手动合并成一个 combinedResults,再拿这个合并后的数组去渲染 HTML。讲完这个能跑但不是最优写法之后,顺带用「三个人在超市拿三样东西」的比喻讲了同步(synchronous)和异步(asynchronous)的区别,为下一讲重构埋下伏笔。
涉及文件
wp-content/themes/fictional-university-theme/src/modules/Search.js(修改,getResults()从只查 posts 改成先查 posts 再嵌套查 pages,合并两个数组)
代码实现
📌 以下代码根据 transcript 口述复原,未对照代码快照核实:
// wp-content/themes/fictional-university-theme/src/modules/Search.js
// 修改:getResults() 改成嵌套请求 posts + pages,手动 concat 合并结果
getResults() {
$.getJSON(universityData.root_url + "/wp-json/wp/v2/posts?search=" + this.searchField.val(), posts => {
$.getJSON(universityData.root_url + "/wp-json/wp/v2/pages?search=" + this.searchField.val(), pages => {
var combinedResults = posts.concat(pages)
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
})
})
}
要点(按 transcript 描述的操作过程):
- 原本负责生成 HTML 的那一段代码(从
this.resultsDiv.html(...)到this.isSpinnerVisible = false)被整段剪切,粘贴到了新加的第二个$.getJSON()回调里面,而不是留在第一个回调里。 - 第二个
$.getJSON()的网址跟第一个几乎一样,只是把posts换成pages,回调参数名取成pages。 - 新增一行
var combinedResults = posts.concat(pages),放在生成 HTML 之前:.concat()是 JS 数组自带的方法,把两个数组首尾拼接成一个新数组。 - 原本模板字符串里三处用到
posts(两处长度判断 + 一处.map())全部替换成combinedResults,这样渲染的列表才是「posts + pages」的合并结果,而不是只有 posts。 - transcript 里讲师明确说这不是最好的写法:因为第二个请求要等第一个请求完全返回之后才会开始发出去(一个套一个,本质上是同步等待的思路),访客要多等一段时间。这个问题会在下一讲用
$.when().then()解决,让两个请求同时(异步)发出去。
Hook / Function 速查
| 名称 | 类型 | 用途 |
|---|---|---|
Array.prototype.concat() | JS 内建数组方法 | 把两个数组首尾拼接合并成一个新数组,不改变原数组 |
嵌套 $.getJSON() | jQuery 用法(写法本身,非新 API) | 在一个请求的回调里再发起另一个请求,效果上是"等第一个做完才开始第二个" |
| synchronous / asynchronous(同步/异步) | 编程概念,非具体 function | 同步:任务依次排队等待完成;异步:多个任务可以同时进行,不用互相等 |
常见坑
transcript 没有提到具体的报错或踩坑,反而是明确指出这一讲的写法本身「不是最佳实践」——两个请求嵌套等于强制它们排队执行(同步思路),拖慢了整体响应速度,属于讲师故意先展示"能跑但不够好"的版本,好让下一讲的重构有对比意义。
延伸 / 后续讲座会用到
下一讲 EP072 会立刻把这里嵌套写的两个 $.getJSON() 重构成 $.when(...).then(...),让两个请求同时(异步)发出去,并加上失败时的错误提示。
Sources
Udemy:
- Become a WordPress Developer: Unlocking Power With Code — Section 14, EP071