Synchronous vs Asynchronous (Searching Multiple Post Types)
Masalah: Hanya Bisa Search 1 Post Type
Kode sebelumnya hanya mengirim request ke /wp-json/wp/v2/posts. Jika user search "about", page "About Us" tidak akan muncul.
Mengganti posts ke pages hanya membalik masalah — blog posts tidak muncul.
Cara 1: Nested getJSON (Synchronous) — ❌ Lambat
js
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;
});
});
}Kenapa Lambat?
Request kedua (pages) menunggu request pertama (posts) selesai. Ini = synchronous — satu per satu.
Analogi: Grocery Store (Sinkron vs Asinkron)
Synchronous (Sinkron)
Bayangkan 3 orang di supermarket, harus ambil 3 barang:
- Orang 1 jalan ambil barang → orang 2 & 3 diam menunggu
- Orang 1 selesai → baru orang 2 jalan → orang 3 masih menunggu
- Orang 2 selesai → baru orang 3 jalan
- Sangat lambat karena banyak waktu menunggu
Asynchronous (Asinkron)
- Orang 1, 2, 3 jalan bersamaan ambil barang masing-masing
- Tidak ada yang menunggu orang lain
- Jauh lebih cepat
Cara 2: $.when().then() (Asynchronous) — ✅ Cepat
js
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) => {
// Combine results
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>');
});
}Penjelasan $.when().then():
| Bagian | Fungsi |
|---|---|
$.when(req1, req2) | Jalankan semua request bersamaan (asynchronous) |
.then(successFn, errorFn) | Jalankan setelah semua request selesai |
(posts, pages) => | Parameter otomatis di-map: request pertama → posts, request kedua → pages |
posts[0] | Index [0] = JSON data murni (karena when/then mengembalikan array [data, statusText, jqXHR]) |
.concat() | Menggabungkan 2 array menjadi 1 |
Kenapa Perlu [0]?
Saat menggunakan $.when().then(), setiap parameter bukan hanya JSON data, tapi array berisi:
js
[jsonData, statusText, jqXHRObject]posts[0]= JSON data (array of post objects)posts[1]= status text ("success")posts[2]= jqXHR object
Tanpa $.when().then() (callback biasa), parameter langsung berisi JSON data saja.
Perbedaan getJSON biasa vs $.when().then():
| Fitur | Nested getJSON | $.when().then() |
|---|---|---|
| Eksekusi | Sequential (satu per satu) | Parallel (bersamaan) |
| Kecepatan | Lambat | Lebih cepat |
| Parameter callback | Langsung JSON data | Array [data, status, jqXHR] |
| Akses data | posts | posts[0] |
Error Handling
Argument kedua di .then() = error callback:
js
.then(
(posts, pages) => {
// success code...
},
() => {
// error code
this.resultsDiv.html('<p>Unexpected error; please try again.</p>');
}
);Jika ada network error atau URL salah, pesan error ditampilkan alih-alih JavaScript crash.
Kode Lengkap getResults():
js
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>');
});
}