From 0273a8d478076cd4c6441c77af6f1369821107f6 Mon Sep 17 00:00:00 2001 From: tegarjgap Date: Thu, 1 Oct 2020 22:00:53 +0700 Subject: [PATCH 1/2] translate into indonesian --- .../01-error-async/solution.md | 8 +- .../01-error-async/task.md | 6 +- .../04-promise-error-handling/article.md | 134 +++++++++--------- 3 files changed, 72 insertions(+), 76 deletions(-) diff --git a/1-js/11-async/04-promise-error-handling/01-error-async/solution.md b/1-js/11-async/04-promise-error-handling/01-error-async/solution.md index 0d43f55e0..ba38b4ba7 100644 --- a/1-js/11-async/04-promise-error-handling/01-error-async/solution.md +++ b/1-js/11-async/04-promise-error-handling/01-error-async/solution.md @@ -1,13 +1,13 @@ -The answer is: **no, it won't**: +Jawabannya adalah: **tidak, tidak terpicu**: ```js run -new Promise(function(resolve, reject) { +new Promise(function (resolve, reject) { setTimeout(() => { throw new Error("Whoops!"); }, 1000); }).catch(alert); ``` -As said in the chapter, there's an "implicit `try..catch`" around the function code. So all synchronous errors are handled. +Seperti yang dikatakan di bab, ada sebuah "`try..catch` implisit" di sekitar kode function. jadi semua error synchronous ditangani. -But here the error is generated not while the executor is running, but later. So the promise can't handle it. +Tetapi di sini error tersebut tidak dihasilkan saat eksekutornya berjalan, tapi nanti. Jadi promise tidak dapat menanganinya. diff --git a/1-js/11-async/04-promise-error-handling/01-error-async/task.md b/1-js/11-async/04-promise-error-handling/01-error-async/task.md index bafc47ce9..6a68fb852 100644 --- a/1-js/11-async/04-promise-error-handling/01-error-async/task.md +++ b/1-js/11-async/04-promise-error-handling/01-error-async/task.md @@ -1,9 +1,9 @@ -# Error in setTimeout +# Error di dalam setTimeout -What do you think? Will the `.catch` trigger? Explain your answer. +Apa yang anda pikirkan? Akankan `.catch` terpicu? Jelaskan jawaban anda. ```js -new Promise(function(resolve, reject) { +new Promise(function (resolve, reject) { setTimeout(() => { throw new Error("Whoops!"); }, 1000); diff --git a/1-js/11-async/04-promise-error-handling/article.md b/1-js/11-async/04-promise-error-handling/article.md index 624c7e812..5a51a8f30 100644 --- a/1-js/11-async/04-promise-error-handling/article.md +++ b/1-js/11-async/04-promise-error-handling/article.md @@ -1,21 +1,20 @@ +# Penanganan error dengan promise -# Error handling with promises +Chain promise bagus dalam penanganan _error_. ketika sebuah promise me-reject, kontrolnya melompat ke handler rejection terdekat. Itu sangat nyaman dalam praktiknya. -Promise chains are great at error handling. When a promise rejects, the control jumps to the closest rejection handler. That's very convenient in practice. - -For instance, in the code below the URL to `fetch` is wrong (no such site) and `.catch` handles the error: +Sebagai contoh, kode di bawah sebuah URL ke `fetch` itu salah (tidak ada situs seperti itu) dan `.catch` menangani error tersebut: ```js run *!* -fetch('https://no-such-server.blabla') // rejects +fetch('https://no-such-server.blabla') // reject */!* .then(response => response.json()) - .catch(err => alert(err)) // TypeError: failed to fetch (the text may vary) + .catch(err => alert(err)) // TypeError: gagal untuk mengambil (teksnya mungkin berbeda) ``` -As you can see, the `.catch` doesn't have to be immediate. It may appear after one or maybe several `.then`. +Seperti yang anda lihat, `.catch` tidak harus segera. `.catch` mungkin muncul setelah satu atau mungkin beberapa `.then`. -Or, maybe, everything is all right with the site, but the response is not valid JSON. The easiest way to catch all errors is to append `.catch` to the end of chain: +Atau, mungkin, semuanya baik-baik saja dengan situs tersebut, tetapi response-nya bukan JSON yang valid. Cara termudah untuk catch semua _error_ adalah menambahkan `.catch` sampai ke akhir chain: ```js run fetch('/article/promise-chaining/user.json') @@ -38,13 +37,13 @@ fetch('/article/promise-chaining/user.json') */!* ``` -Normally, such `.catch` doesn't trigger at all. But if any of the promises above rejects (a network problem or invalid json or whatever), then it would catch it. +Biasanya, `.catch` semacam itu tidak memicu sama sekali. Tetapi jika salah satu promise di atas me-reject (sebuah masalah jaringan atau json yang tidak valid atau apapun itu), maka promise tersebut akan meng-catch-nya. -## Implicit try..catch +## try..catch implisit -The code of a promise executor and promise handlers has an "invisible `try..catch`" around it. If an exception happens, it gets caught and treated as a rejection. +Kode dari sebuah eksekutor promise dan handler promise memiliki "`try..catch` yang tak terlihat" di sekitarnya. Jika terjadi pengecualian, maka pengecualian itu tertangkap dan diperlakukan sebagai rejection. -For instance, this code: +Sebagai contoh, kode ini: ```js run new Promise((resolve, reject) => { @@ -54,75 +53,73 @@ new Promise((resolve, reject) => { }).catch(alert); // Error: Whoops! ``` -...Works exactly the same as this: +...Bekerja persis sama seperti ini: ```js run new Promise((resolve, reject) => { *!* reject(new Error("Whoops!")); -*/!* +*/!* }).catch(alert); // Error: Whoops! ``` -The "invisible `try..catch`" around the executor automatically catches the error and turns it into rejected promise. +"`try..catch` yang tak terlihat" di sekitar eksekutor secara otomatis menangkap _error_ dan mengubahnya menjadi promise yang direject. -This happens not only in the executor function, but in its handlers as well. If we `throw` inside a `.then` handler, that means a rejected promise, so the control jumps to the nearest error handler. +Ini terjadi bukan hanya di dalam function eksekutor saja, tetapi di handler-nya juga. Jika kita `throw` dalam handler `.then`, itu artinya sebuah promise yang direject, jadi kontrolnya melompat ke handler error terdekat. -Here's an example: +Ini contohnya: ```js run new Promise((resolve, reject) => { resolve("ok"); }).then((result) => { *!* - throw new Error("Whoops!"); // rejects the promise + throw new Error("Whoops!"); // reject promise tersebut */!* }).catch(alert); // Error: Whoops! ``` -This happens for all errors, not just those caused by the `throw` statement. For example, a programming error: +Ini terjadi pada semua _error_, tidak hanya disebabkan oleh pernyataan `throw`. Sebagai contoh, sebuah _error_ pemrograman: ```js run new Promise((resolve, reject) => { resolve("ok"); }).then((result) => { *!* - blabla(); // no such function + blabla(); // tidak ada fungsi seperti ini */!* -}).catch(alert); // ReferenceError: blabla is not defined +}).catch(alert); // ReferenceError: blabla tidak terdefinisi ``` -The final `.catch` not only catches explicit rejections, but also occasional errors in the handlers above. +`.catch` terakhir tidak hanya meng-catch rejection secara ekplisit, tetapi juga sesekali _error_ dalam handler di atas. -## Rethrowing +## Melempar kembali -As we already noticed, `.catch` at the end of the chain is similar to `try..catch`. We may have as many `.then` handlers as we want, and then use a single `.catch` at the end to handle errors in all of them. +Seperti yang sudah kita perhatikan, `.catch` di akhir chain mirip dengan `try..catch`. Kita bisa saja memiliki sebanyak mungkin handler `.then` seperti yang kita inginkan, dan kemudian menggunakan satu `.catch` di akhir untuk menangani _error_ di semuanya. -In a regular `try..catch` we can analyze the error and maybe rethrow it if can't handle. The same thing is possible for promises. +Di dalam `try..catch` biasa kita dapat menganalisis _error_ nya dan mungkin melemparkannya kembali jika tidak bisa ditangani. Hal yang sama mungkin untuk promise. -If we `throw` inside `.catch`, then the control goes to the next closest error handler. And if we handle the error and finish normally, then it continues to the closest successful `.then` handler. +Jika kita `throw` di dalam `.catch`, kemudian kontrolnya mengarah ke handler _error_ terdekat selanjutnya. Dan jika kita menangani _error_ dan selesai dengan normal, kemudian berlanjut ke handler `.then` sukses terdekat berikutnya. -In the example below the `.catch` successfully handles the error: +Pada contoh di bawah ini `.catch` sukses menangani _error_: ```js run -// the execution: catch -> then +// eksekusi: catch -> then new Promise((resolve, reject) => { - throw new Error("Whoops!"); - -}).catch(function(error) { - - alert("The error is handled, continue normally"); - -}).then(() => alert("Next successful handler runs")); +}) + .catch(function (error) { + alert("The error is handled, continue normally"); + }) + .then(() => alert("Next successful handler runs")); ``` -Here the `.catch` block finishes normally. So the next successful `.then` handler is called. +Disini blok `.catch` selesai secara normal. Jadi handler `.then` yang sukses selanjutnya dipanggil. -In the example below we see the other situation with `.catch`. The handler `(*)` catches the error and just can't handle it (e.g. it only knows how to handle `URIError`), so it throws it again: +Pada contoh di bawah ini kita lihat situasi lain dengan `.catch`. Handler `(*)` menangkap _error_ dan tidak bisa mengatasinya (misalnya hanya tahu bagaimana menangani `URIError`), jadi _error_-nya dilempar lagi: ```js run -// the execution: catch -> catch -> then +// eksekusi: catch -> catch -> then new Promise((resolve, reject) => { throw new Error("Whoops!"); @@ -130,75 +127,74 @@ new Promise((resolve, reject) => { }).catch(function(error) { // (*) if (error instanceof URIError) { - // handle it + // tangani di sini } else { alert("Can't handle such error"); *!* - throw error; // throwing this or another error jumps to the next catch + throw error; // lemparkan ini atau error lain melompat ke catch selanjutnya */!* } }).then(function() { - /* doesn't run here */ + /* tidak berjalan di sini */ }).catch(error => { // (**) alert(`The unknown error has occurred: ${error}`); - // don't return anything => execution goes the normal way + // tidak mengembalikkan apapun => eksekusi berjalan normal }); ``` -The execution jumps from the first `.catch` `(*)` to the next one `(**)` down the chain. +Eksekusi tersebut melompat dari `.catch` `(*)` pertama ke yang selanjutnya `(**)` menuruni chain. -## Unhandled rejections +## Rejection yang tidak tertangani -What happens when an error is not handled? For instance, we forgot to append `.catch` to the end of the chain, like here: +Apa yang terjadi ketika sebuah _error_ tidak ditangani? Sebagai contoh, kita lupa untuk menambahkan `.catch` ke akhir chain, seperti ini: ```js untrusted run refresh -new Promise(function() { - noSuchFunction(); // Error here (no such function) -}) - .then(() => { - // successful promise handlers, one or more - }); // without .catch at the end! +new Promise(function () { + noSuchFunction(); // Error di sini (tidak ada function seperti itu) +}).then(() => { + // handler promise yang sukses, satu atau lebih +}); // tanpa .catch di akhir! ``` -In case of an error, the promise becomes rejected, and the execution should jump to the closest rejection handler. But there is none. So the error gets "stuck". There's no code to handle it. +Jika terjadi _error_, promise jadi direject, dan eksekusi harus melompat ke handler penolakan terdekat. Tapi tidak ada. Jadi _error_-nya "stuck". Tidak ada kode untuk menangani-nya. -In practice, just like with regular unhandled errors in code, it means that something has terribly gone wrong. +Dalam prakteknya, seperti _error_ biasa yang tidak tertangani dalam kode, itu berarti ada sesuatu yang tidak beres. -What happens when a regular error occurs and is not caught by `try..catch`? The script dies with a message in console. Similar thing happens with unhandled promise rejections. +Apa yang terjadi ketika sebuah _error_ biasa muncul dan tidak tertangkap oleh `try..catch`? script-nya mati dengan sebuah pesan di console. Sesuatu yang mirip terjadi dengan rejection promise yang tidak tertangani. -JavaScript engine tracks such rejections and generates a global error in that case. You can see it in the console if you run the example above. +Mesin JavaScript melacak rejection tersebut dan menghasilkan _error_ global dalam kasus itu. Anda dapat melihatnya di console jika anda menjalankan contoh di atas. -In the browser we can catch such errors using the event `unhandledrejection`: +Di dalam peramban kita dapat meng-catch kesalahan tersebut menggunakan event `unhandledrejection`: ```js run *!* window.addEventListener('unhandledrejection', function(event) { - // the event object has two special properties: - alert(event.promise); // [object Promise] - the promise that generated the error - alert(event.reason); // Error: Whoops! - the unhandled error object + // object event tersebut memiliki dua properti spesial: + alert(event.promise); // [object Promise] - promise yang menghasilkan error + alert(event.reason); // Error: Whoops! - object error yang tidak tertangani }); */!* new Promise(function() { throw new Error("Whoops!"); -}); // no catch to handle the error +}); // tidak ada catch untuk menangani error ``` -The event is the part of the [HTML standard](https://html.spec.whatwg.org/multipage/webappapis.html#unhandled-promise-rejections). +Event tersebut adalah bagian dari [standar HTML](https://html.spec.whatwg.org/multipage/webappapis.html#unhandled-promise-rejections). -If an error occurs, and there's no `.catch`, the `unhandledrejection` handler triggers, and gets the `event` object with the information about the error, so we can do something. +Jika sebuah _error_ muncul, dan di sana tidak ada `.catch`, handler `unhandledrejection` terpicu, dan mendapatkan object `event` dengan informasi tentang _error_, jadi kita dapat melakukan sesuatu. -Usually such errors are unrecoverable, so our best way out is to inform the user about the problem and probably report the incident to the server. +Biasanya _error_ seperti itu tidak dapat dipulihkan, jadi jalan keluar terbaik kita adalah memberi tahu pengguna tentang masalah dan mungkin melaporkan insiden tersebut ke server. -In non-browser environments like Node.js there are other ways to track unhandled errors. +Di dalam lingkungan non-peramban seperti Node.js di sana ada cara lain untuk melacak _error_ yang tak tertangani. -## Summary +## Ringkasan -- `.catch` handles errors in promises of all kinds: be it a `reject()` call, or an error thrown in a handler. -- We should place `.catch` exactly in places where we want to handle errors and know how to handle them. The handler should analyze errors (custom error classes help) and rethrow unknown ones (maybe they are programming mistakes). -- It's ok not to use `.catch` at all, if there's no way to recover from an error. -- In any case we should have the `unhandledrejection` event handler (for browsers, and analogs for other environments), to track unhandled errors and inform the user (and probably our server) about the them, so that our app never "just dies". +- `.catch` menangani _error_ di segala macam promise: baik itu panggilan `reject()`, atau sebuah _error_ yang dilemparkan di dalam handler. +- Kita harus meletakkan `.catch` tepat di tempat dimana kita ingin menangani _error_ dan tahu bagaimana untuk menangani _error-error_ tersebut. Handler harus menganalisa _error_ (bantuan class _error_ khusus) dan melemparkan kembali yang tidak diketahui (mungkin itu adalah kesalahan pemrograman). +- Ok untuk tidak menggunakan `.catch` sama sekali, jika tidak ada cara untuk memulihkan dari kesalahan. +- Bagaimanapun kita harus memiliki handler event `unhandledrejection` (untuk peramban,dan analog untuk lingkungan lainnya), untuk melacak _error_ yang tak tertangani dan memberi tahu pengguna (dan mungkin server kita) tentang _error-error_ tersebut, jadi aplikasi kita tidak pernah "mati begitu saja". From 7ae3d6058dd67718e28c8d9a98b34072e42665b3 Mon Sep 17 00:00:00 2001 From: tegarjgap Date: Fri, 2 Oct 2020 03:30:08 +0700 Subject: [PATCH 2/2] translating into Indonesian --- 1-js/11-async/05-promise-api/article.md | 242 +++++++++++++----------- 1 file changed, 128 insertions(+), 114 deletions(-) diff --git a/1-js/11-async/05-promise-api/article.md b/1-js/11-async/05-promise-api/article.md index d439c8238..26fc14882 100644 --- a/1-js/11-async/05-promise-api/article.md +++ b/1-js/11-async/05-promise-api/article.md @@ -1,83 +1,84 @@ -# Promise API +# API Promise -There are 5 static methods in the `Promise` class. We'll quickly cover their use cases here. +Ada 5 method static di dalam class `Promise`. Kita akan segera membahas kasus penggunaan method-method tersebut di sini. ## Promise.all -Let's say we want to run many promises to execute in parallel, and wait till all of them are ready. +Katakanlah kita ingin menjalankan banyak promise untuk dieksekusi secara paralel, dan menunggu sampai semua promise tersebut siap. -For instance, download several URLs in parallel and process the content when all are done. +Sebagai contoh, unduh beberapa URL secara paralel dan proses isinya ketika semuanya selesai. -That's what `Promise.all` is for. +Itulah gunanya `Promise.all`. -The syntax is: +Sintaksis nya adalah: ```js let promise = Promise.all([...promises...]); ``` -`Promise.all` takes an array of promises (technically can be any iterable, but usually an array) and returns a new promise. +`Promise.all` mengambil sebuah array promise (secara teknis bisa menjadi iterable, tetapi biasanya sebuah array) dan mengembalikkan promise baru. -The new promise resolves when all listed promises are settled and the array of their results becomes its result. +Promise baru resolve ketika semua promise yang terdaftar diselesaikan dan array dari hasil promise menjadi hasilnya itu sendiri. -For instance, the `Promise.all` below settles after 3 seconds, and then its result is an array `[1, 2, 3]`: +Sebagai contoh, `Promise.all` di bawah selesai setelah 3 detik, dan kemudian hasilnya adalah sebuah array `[1, 2, 3]`: ```js run Promise.all([ - new Promise(resolve => setTimeout(() => resolve(1), 3000)), // 1 - new Promise(resolve => setTimeout(() => resolve(2), 2000)), // 2 - new Promise(resolve => setTimeout(() => resolve(3), 1000)) // 3 -]).then(alert); // 1,2,3 when promises are ready: each promise contributes an array member + new Promise((resolve) => setTimeout(() => resolve(1), 3000)), // 1 + new Promise((resolve) => setTimeout(() => resolve(2), 2000)), // 2 + new Promise((resolve) => setTimeout(() => resolve(3), 1000)), // 3 +]).then(alert); // 1,2,3 ketika promise sudah siap: setiap promise menyumbangkan sebuah member array ``` -Please note that the order of resulting array members is the same as source promises. Even though the first promise takes the longest time to resolve, it's still first in the array of results. +Harap dicatat bahwa urutan member array yang dihasilkan adalah sama dengan sumber promise. Meskipun promise pertama membutuhkan waktu yang lama untuk resolve, promise tersebut masih yang pertama di dalam hasil array. -A common trick is to map an array of job data into an array of promises, and then wrap that into `Promise.all`. +Sebuah trik umum adalah untuk memetakan sebuah array dari data pekerjaan kedalam array promise, dan kemudian membungkusnya kedalam `Promise.all`. -For instance, if we have an array of URLs, we can fetch them all like this: +Sebagai contoh, jika kita memiliki array URL, kita dapat mengambil array-array tersebut seperti ini: ```js run let urls = [ - 'https://api.github.com/users/iliakan', - 'https://api.github.com/users/remy', - 'https://api.github.com/users/jeresig' + "https://api.github.com/users/iliakan", + "https://api.github.com/users/remy", + "https://api.github.com/users/jeresig", ]; -// map every url to the promise of the fetch -let requests = urls.map(url => fetch(url)); +// memetakan setiap url ke pengambilan promise +let requests = urls.map((url) => fetch(url)); -// Promise.all waits until all jobs are resolved -Promise.all(requests) - .then(responses => responses.forEach( - response => alert(`${response.url}: ${response.status}`) - )); +// Promise.all menunggu sampai semua pekerjaan telah diresolve +Promise.all(requests).then((responses) => + responses.forEach((response) => alert(`${response.url}: ${response.status}`)) +); ``` -A bigger example with fetching user information for an array of GitHub users by their names (we could fetch an array of goods by their ids, the logic is same): +Contoh terbesar dengan mengambil informasi pengguna untuk sebuah array pengguna GitHub dengan nama mereka (kita dapat mengambil array dengan id mereka, logika nya sama): ```js run -let names = ['iliakan', 'remy', 'jeresig']; +let names = ["iliakan", "remy", "jeresig"]; -let requests = names.map(name => fetch(`https://api.github.com/users/${name}`)); +let requests = names.map((name) => + fetch(`https://api.github.com/users/${name}`) +); Promise.all(requests) - .then(responses => { - // all responses are resolved successfully - for(let response of responses) { - alert(`${response.url}: ${response.status}`); // shows 200 for every url + .then((responses) => { + // semua response telah sukses diresolve + for (let response of responses) { + alert(`${response.url}: ${response.status}`); // menunjukkan 200 untuk setiap url } return responses; }) - // map array of responses into array of response.json() to read their content - .then(responses => Promise.all(responses.map(r => r.json()))) - // all JSON answers are parsed: "users" is the array of them - .then(users => users.forEach(user => alert(user.name))); + // memetakan array response kedalam array response.json() untuk membaca isinya + .then((responses) => Promise.all(responses.map((r) => r.json()))) + // semua jawaban JSON diuraikan: "users" adalah array dari jawaban tersebut + .then((users) => users.forEach((user) => alert(user.name))); ``` -**If any of the promises is rejected, the promise returned by `Promise.all` immediately rejects with that error.** +**Jika ada promise yang direject, promise tersebut dikembalikkan oleh `Promise.all` secara langsung me-reject nya dengan error itu.** -For instance: +Sebagai contoh: ```js run Promise.all([ @@ -89,78 +90,79 @@ Promise.all([ ]).catch(alert); // Error: Whoops! ``` -Here the second promise rejects in two seconds. That leads to immediate rejection of `Promise.all`, so `.catch` executes: the rejection error becomes the outcome of the whole `Promise.all`. +Disini promise kedua reject dalam dua detik. Itu langsung mengarah pada rejection `Promise.all`, jadi eksekusi `.catch`: error rejection menjadi hasil keseluruhan `Promise.all`. -```warn header="In case of an error, other promises are ignored" -If one promise rejects, `Promise.all` immediately rejects, completely forgetting about the other ones in the list. Their results are ignored. +```warn header="Jika terjadi sebuah error, promise lain diabaikan" +Jika satu promise reject, `Promise.all` langsung reject, benar-benar melupakan yang lainnya yang ada di dalam daftar. Hasil dari promise-promise tersebut diabaikan. -For example, if there are multiple `fetch` calls, like in the example above, and one fails, other ones will still continue to execute, but `Promise.all` won't watch them anymore. They will probably settle, but the result will be ignored. +Sebagai contoh, jika disana ada banyak pemanggilan `fetch`, seperti contoh di atas, dan satu gagal, yang lainnya akan terus mengeksekusi, tetapi `Promise.all` tidak akan memperhatikan promise-promisenya lagi. Promise-promise tersebut mungkin selesai, tetapi hasilnya akan diabaikan. -`Promise.all` does nothing to cancel them, as there's no concept of "cancellation" in promises. In [another chapter](info:fetch-abort) we'll cover `AbortController` that can help with that, but it's not a part of the Promise API. +`Promise.all` tidak melakukan apapun untuk membatalkan promise-promise tersebut, karena tidak ada konsep "pembatalan" di dalam promise. Di [bab lainnya](info:fetch-abort) kita akan membahas `AbortController` yang bisa membantu, tetapi `AbortController` tersebut bukan bagian dari API Promise. ``` -````smart header="`Promise.all(iterable)` allows non-promise \"regular\" values in `iterable`" -Normally, `Promise.all(...)` accepts an iterable (in most cases an array) of promises. But if any of those objects is not a promise, it's passed to the resulting array "as is". +````smart header="`Promise.all(iterable)`memungkinkan nilai \"regular\" non-promise di dalam `iterable`" Secara normal, `Promise.all(...)` menerima sebuah promise iterable (dalam banyak kasus sebuah array). Tetapi jika salah satu objek bukan promise, objek tersebut diteruskan ke array yang dihasilkan "sebagaimana adanya". -For instance, here the results are `[1, 2, 3]`: +Sebagai contoh, berikut hasilnya `[1, 2, 3]`: ```js run Promise.all([ new Promise((resolve, reject) => { - setTimeout(() => resolve(1), 1000) + setTimeout(() => resolve(1), 1000); }), 2, - 3 + 3, ]).then(alert); // 1, 2, 3 ``` -So we are able to pass ready values to `Promise.all` where convenient. +Jadi kita dapat meneruskan nilai yang sudah siap ke `Promise.all` jika nyaman. + ```` ## Promise.allSettled [recent browser="new"] -`Promise.all` rejects as a whole if any promise rejects. That's good for "all or nothing" cases, when we need *all* results to go on: +`Promise.all` reject seluruhnya jika ada promise yang reject. Itu bagus untuk kasus "semua atau tidak sama sekali", ketika kita membutuhkan *semua* hasil untuk melanjutkan: ```js Promise.all([ fetch('/template.html'), fetch('/style.css'), fetch('/data.json') -]).then(render); // render method needs results of all fetches -``` +]).then(render); // method render butuh hasil dari semua pengambilan +```` -`Promise.allSettled` waits for all promises to settle. The resulting array has: +`Promise.allSettled` menunggu semua promise selesai. Array yang dihasilkan memiliki: -- `{status:"fulfilled", value:result}` for successful responses, -- `{status:"rejected", reason:error}` for errors. +- `{status:"fulfilled", value:result}` untuk response sukses, +- `{status:"rejected", reason:error}` untuk error. -For example, we'd like to fetch the information about multiple users. Even if one request fails, we're still interested in the others. +Sebagai contoh, kita ingin mengambil informasi tentang banyak pengguna. Bahkan jika satu request gagal, kita masih tertarik pada yang request yang lain. -Let's use `Promise.allSettled`: +Mari gunakan `Promise.allSettled`: ```js run let urls = [ - 'https://api.github.com/users/iliakan', - 'https://api.github.com/users/remy', - 'https://no-such-url' + "https://api.github.com/users/iliakan", + "https://api.github.com/users/remy", + "https://no-such-url", ]; -Promise.allSettled(urls.map(url => fetch(url))) - .then(results => { // (*) - results.forEach((result, num) => { - if (result.status == "fulfilled") { - alert(`${urls[num]}: ${result.value.status}`); - } - if (result.status == "rejected") { - alert(`${urls[num]}: ${result.reason}`); - } - }); +Promise.allSettled(urls.map((url) => fetch(url))).then((results) => { + // (*) + results.forEach((result, num) => { + if (result.status == "fulfilled") { + alert(`${urls[num]}: ${result.value.status}`); + } + if (result.status == "rejected") { + alert(`${urls[num]}: ${result.reason}`); + } }); +}); ``` -The `results` in the line `(*)` above will be: +`results` pada baris `(*)` di atas akan: + ```js [ {status: 'fulfilled', value: ...response...}, @@ -169,72 +171,80 @@ The `results` in the line `(*)` above will be: ] ``` -So, for each promise we get its status and `value/error`. +Jadi, untuk setiap promise kita mendapatkan status-nya dan `value/error`. ### Polyfill -If the browser doesn't support `Promise.allSettled`, it's easy to polyfill: +Jika peramban tidak mendukung `Promise.allSettled`, mudah untuk melakukan polyfill: ```js -if(!Promise.allSettled) { - Promise.allSettled = function(promises) { - return Promise.all(promises.map(p => Promise.resolve(p).then(value => ({ - state: 'fulfilled', - value - }), reason => ({ - state: 'rejected', - reason - })))); +if (!Promise.allSettled) { + Promise.allSettled = function (promises) { + return Promise.all( + promises.map((p) => + Promise.resolve(p).then( + (value) => ({ + state: "fulfilled", + value, + }), + (reason) => ({ + state: "rejected", + reason, + }) + ) + ) + ); }; } ``` -In this code, `promises.map` takes input values, turns into promises (just in case a non-promise was passed) with `p => Promise.resolve(p)`, and then adds `.then` handler to every one. +Dalam kode ini, `promises.map` mengambil nilai input, berubah menjadi promises (untuk berjaga-jaga jika non-promise yang diteruskan) dengan `p => Promise.resolve(p)`, dan kemudian menambahkan handler `.then` handler ke semuanya. -That handler turns a successful result `v` into `{state:'fulfilled', value:v}`, and an error `r` into `{state:'rejected', reason:r}`. That's exactly the format of `Promise.allSettled`. +Handler tersebut mengubah hasil `v` yang sukses menjadi `{state:'fulfilled', value:v}`, dan sebuah error `r` menjadi `{state:'rejected', reason:r}`. Itu persis dengan format `Promise.allSettled`. -Then we can use `Promise.allSettled` to get the results or *all* given promises, even if some of them reject. +Kita bisa menggunakan `Promise.allSettled` untuk mendapatkan hasilnya atau _semua_ promise diberikan, bahkan jika beberapa dari promise itu reject. ## Promise.race -Similar to `Promise.all`, but waits only for the first settled promise, and gets its result (or error). +Mirip dengan `Promise.all`, tetapi hanya menunggu promise pertama diselesaikan, dan mendapatkan hasilnya (atau error). -The syntax is: +Sintaksisnya adalah: ```js let promise = Promise.race(iterable); ``` -For instance, here the result will be `1`: +Sebagai contoh, hasil di sini akan menjadi `1`: ```js run Promise.race([ new Promise((resolve, reject) => setTimeout(() => resolve(1), 1000)), - new Promise((resolve, reject) => setTimeout(() => reject(new Error("Whoops!")), 2000)), - new Promise((resolve, reject) => setTimeout(() => resolve(3), 3000)) + new Promise((resolve, reject) => + setTimeout(() => reject(new Error("Whoops!")), 2000) + ), + new Promise((resolve, reject) => setTimeout(() => resolve(3), 3000)), ]).then(alert); // 1 ``` -The first promise here was fastest, so it became the result. After the first settled promise "wins the race", all further results/errors are ignored. - +Promise pertama di sini adalah yang tercepat, jadi promise tersebut menjadi hasilnya. Setelah promise pertama yang selesai "memenangkan balapan", semua hasil/errors lebih lanjut akan diabaikan. ## Promise.resolve/reject -Methods `Promise.resolve` and `Promise.reject` are rarely needed in modern code, because `async/await` syntax (we'll cover it in [a bit later](info:async-await)) makes them somewhat obsolete. +Method `Promise.resolve` dan `Promise.reject` jarang dibutuhkan dalam kode modern, karena sintaksis `async/await` (kita akan membahasnya [nanti](info:async-await)) membuat method-method tersebut usang. -We cover them here for completeness, and for those who can't use `async/await` for some reason. +Kita membahas method-method tersebut di sini sebagai pelengkap, dan bagi mereka yang tidak bisa menggunakan `async/await` untuk beberapa alasan. -- `Promise.resolve(value)` creates a resolved promise with the result `value`. +- `Promise.resolve(value)` membuat promise yang diresolve dengan hasil `value`. -Same as: +Sama dengan: ```js -let promise = new Promise(resolve => resolve(value)); +let promise = new Promise((resolve) => resolve(value)); ``` -The method is used for compatibility, when a function is expected to return a promise. +Method ini digunakan untuk kompatibilitas, ketika function diharapkan untuk mengembalikkan promise. -For example, `loadCached` function below fetches URL and remembers (caches) its content. For future calls with the same URL it immediately gets the previous content from cache, but uses `Promise.resolve` to make a promise of it, so that the returned value is always a promise: +Sebagai contoh, function `loadCached` di bawah mengambil URL dan mengingat (cache) isinya. Untuk panggilan di masa mendatang dengan URL yang sama itu segera mendapatkan isi sebelumnya dari cache, tetapi menggunakan `Promise.resolve` untuk membuat promise tentang itu, jadi hasil yang dikembalikkan selalu sebuah promise: ```js let cache = new Map(); @@ -255,30 +265,34 @@ function loadCached(url) { } ``` -We can write `loadCached(url).then(…)`, because the function is guaranteed to return a promise. We can always use `.then` after `loadCached`. That's the purpose of `Promise.resolve` in the line `(*)`. +Kita dapat menulis `loadCached(url).then(…)`, karena function tersebut dijamin untuk mengembalikan promise. Kita selalu dapat menggunakan `.then` setelah `loadCached`. Itulah tujuan dari `Promise.resolve` pada baris `(*)`. ### Promise.reject -- `Promise.reject(error)` creates a rejected promise with `error`. +- `Promise.reject(error)` membuat promise yang direjecet dengan `error`. -Same as: +Sama dengan: ```js let promise = new Promise((resolve, reject) => reject(error)); ``` -In practice, this method is almost never used. +Dalam praktiknya, method ini hampir tidak pernah digunakan. + +## Ringkasan -## Summary +Ada 5 method static dari class `Promise`: -There are 5 static methods of `Promise` class: +1. `Promise.all(promises)` -- menunggu semua promise selesai dan mengambalikan sebuah array sebagai hasilnya. Jika salah satu promises yang diberikan reject, maka menjadi error of `Promise.all`, dan semua hasil lainnya akan diabaikan. +2. `Promise.allSettled(promises)` (method yang baru ditambahkan) -- menunggu semua promise selesai dan mengembalikan hasilnya sebagai objek array dengan: + - `state`: `"fulfilled"` or `"rejected"` + - `value` (jika fulfilled) atau `reason` (jika rejected). +3. `Promise.race(promises)` -- menunggu promise pertama selesai, dan hasil/error menjadi hasilnya. +4. `Promise.resolve(value)` -- membuat promise yang resolved dengan nilai yang diberikan. +5. `Promise.reject(error)` -- membuat promise rejected dengan error yang diberikan. -1. `Promise.all(promises)` -- waits for all promises to resolve and returns an array of their results. If any of the given promises rejects, then it becomes the error of `Promise.all`, and all other results are ignored. -2. `Promise.allSettled(promises)` (recently added method) -- waits for all promises to settle and returns their results as array of objects with: - - `state`: `"fulfilled"` or `"rejected"` - - `value` (if fulfilled) or `reason` (if rejected). -3. `Promise.race(promises)` -- waits for the first promise to settle, and its result/error becomes the outcome. -4. `Promise.resolve(value)` -- makes a resolved promise with the given value. -5. `Promise.reject(error)` -- makes a rejected promise with the given error. +Dari lima ini, `Promise.all` mungkin yang paling umum dalam praktiknya. -Of these five, `Promise.all` is probably the most common in practice. +``` + +```