Rumah > hujung hadapan web > tutorial js > Semua yang Anda Perlu Tahu Tentang Janji JavaScript dan Cara Ia Berfungsi

Semua yang Anda Perlu Tahu Tentang Janji JavaScript dan Cara Ia Berfungsi

Patricia Arquette
Lepaskan: 2024-12-17 03:33:25
asal
715 orang telah melayarinya

Everything You Need to Know About JavaScript Promises and How They Work

Pembangunan web moden sangat bergantung pada aktiviti tak segerak untuk membolehkan aplikasi responsif dan interaktif. Sama ada mengambil data daripada API, membaca fail atau menjalankan pemasa, proses ini mesti berjalan di latar belakang tanpa membekukan antara muka. JavaScript menawarkan anda cara yang boleh dipercayai untuk mengendalikan pekerjaan ini. Artikel ini merangkumi semua yang anda perlu tahu tentang janji, termasuk idea asas dan ciri lanjutan, untuk membangunkan atur cara tak segerak tanpa ralat.

Dalam artikel ini anda akan belajar tentang —

  • Apakah itu Janji?

  • Mengapa Gunakan Janji?

  • Bagaimana Janji Berfungsi?

  • Mengendalikan Janji

  • Merangkai Janji

  • Ralat Mengendalikan Janji

  • Ciri Janji Lanjutan

  • Aliran Pelaksanaan JavaScript dengan Janji (Penting)

  • Menukar Rantaian Janji kepada Async/Menunggu

  • Amalan Terbaik dan Kesilapan Biasa

Apa itu Janji?

Janji dalam JavaScript adalah sama dengan membuat "janji" untuk melakukan sesuatu pada masa hadapan. Apabila anda membuat janji, anda berkata, "Saya berjanji untuk memberikan anda hasilnya nanti." Hasil ini boleh menjadi kejayaan atau kegagalan.

Dalam erti kata lain, janji ialah objek yang menggambarkan kejayaan muktamad (atau kegagalan) operasi tak segerak dan nilai terhasilnya. Ia membolehkan anda mengaitkan pengendali dengan kejayaan atau kegagalan tindakan tak segerak, menjadikan kod anda lebih mudah dibaca dan diselenggara.

Mengapa Menggunakan Janji?

Dalam JavaScript, contohnya, operasi yang memakan masa seperti mendapatkan semula data daripada pelayan-biasanya dicapai dengan panggilan balik. Panggilan balik hanyalah fungsi yang dihantar ke fungsi lain untuk dilaksanakan selepas tugas selesai. Anda mungkin menggunakan panggilan balik, sebagai contoh, untuk memproses data apabila ia tiba dari pelayan.

Namun, apabila terdapat operasi yang kompleks, penggunaan panggil balik menjadi agak kemas. Kekacauan ini dikenali sebagai "neraka panggil balik", di mana seseorang boleh mempunyai panggilan balik dalam yang lain, dan ini menjadikan kod tidak boleh dibaca dan tidak terurus.

Contoh Neraka Panggilan Balik:

    fetchData((data) => {
      processData(data, (processedData) => {
        saveData(processedData, (result) => {
          console.log(result);
        });
      });
    });
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Seperti yang ditunjukkan di atas, kod tersebut menjadi semakin sukar untuk dibaca dan diselenggara dalam pangkalan kod yang lebih besar kerana strukturnya yang sangat bersarang, sering dirujuk sebagai "neraka panggilan balik".

Janji telah diperkenalkan untuk menangani masalah ini, menawarkan cara yang lebih bersih dan teratur untuk mengendalikan tugas tak segerak dengan membenarkan rantaian dengan cara yang lebih mudah dibaca.

Pendekatan Berasaskan Janji:

    fetchData((data) => {
      processData(data, (processedData) => {
        saveData(processedData, (result) => {
          console.log(result);
        });
      });
    });
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Pendekatan ini meratakan struktur dan menjadikan kod lebih mudah dibaca dan diselenggara.

Bagaimana Janji Berfungsi?

Janji dalam JavaScript boleh berada dalam salah satu daripada tiga keadaan:

  1. Belum selesai: Ini adalah langkah awal. Janji masih belum ditunaikan.

  2. Ditepati: Janji telah berjaya diselesaikan bermakna ia diselesaikan dan mempunyai nilai.

  3. Ditolak: Janji tidak berjaya diselesaikan, dan ia membawa mesej ralat.

Sintaks Asas

fetchData()
  .then(processData)
  .then(saveData)
  .then(console.log)
  .catch(console.error);
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Dalam contoh ini, janji diselesaikan selepas 1 saat dengan mesej "Janji diselesaikan!". Kaedah.then() digunakan untuk mengendalikan nilai yang diselesaikan.

Mengendalikan Janji

Menggunakan .then() untuk Pengendalian Kejayaan

Kaedah.then() digunakan untuk mengendalikan perkara yang berlaku apabila janji berjaya diselesaikan. Ia mendaftarkan fungsi (panggilan balik) untuk dijalankan apabila janji dipenuhi.

const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("Promise resolved!");
  }, 1000);
});

myPromise.then(result => console.log(result));
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Menggunakan .catch() untuk Pengendalian Ralat

Kaedah.catch() digunakan untuk mengendalikan perkara yang berlaku apabila janji gagal. Ia mendaftarkan fungsi (panggilan balik) untuk dijalankan apabila janji ditolak.

myPromise.then(data => {
  console.log("Data received:", data);
});
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Menggunakan .finally() untuk Pembersihan

Kaedah.finally() membolehkan anda menjalankan beberapa kod selepas janji dilakukan, sama ada ia berjaya atau tidak.

myPromise.catch(error => {
  console.error("Error:", error);
});
Salin selepas log masuk
Salin selepas log masuk

Merangkai Janji

Perantaian membolehkan anda melaksanakan tugasan secara berurutan dengan melepasi keputusan yang sebelumnya. Kemudian teruskan ke seterusnya.then(). Ini membolehkan anda mengendalikan beberapa tugas tak segerak secara berurutan.

Contoh Rantaian:

myPromise.finally(() => {
  console.log("Cleanup tasks");
});
Salin selepas log masuk
Salin selepas log masuk

Contoh ini menggunakan each.then()untuk mengendalikan setiap langkah dalam proses, membolehkan aliran data yang jelas. Ini membolehkan anda melihat cara keputusan satu peringkat dipindahkan ke peringkat seterusnya.

Ralat Pengendalian dalam Janji

Janji memudahkan pengendalian ralat dengan membenarkan mereka menurunkan rantaian kepada kaedah.catch() untuk penyelesaian. Ini menghapuskan keperluan untuk mengendalikan kegagalan pada setiap fasa, memastikan kod anda lebih jelas dan lebih mudah untuk diurus.

Contoh dengan Penyebaran Ralat:

fetch('https://api.example.com/user')
  .then(response => response.json())
  .then(data => {
    console.log("Processed data:", data);
    return processData(data);
  })
  .then(finalResult => {
    console.log("Final result:", finalResult);
  })
  .catch(error => console.error("Error:", error));
Salin selepas log masuk

Jika mana-mana langkah dalam rantai janji gagal, ralat akan ditangkap oleh blok.catch(). Ini memudahkan untuk menangani isu dan memastikan kod anda berjalan lancar.

Ciri Janji Lanjutan

1. Promise.all() untuk Pelaksanaan Selari

Kaedah Promise.all() membolehkan anda menjalankan beberapa janji serentak dan menunggu semuanya selesai. Jika semua janji ditepati, anda akan menerima keputusan setiap satu. Jika mana-mana janji gagal, ia mengesan kesilapan itu.

fetchData()
  .then(processData)
  .then(saveData)
  .catch(error => console.error("An error occurred:", error));
Salin selepas log masuk

Dalam contoh ini, jika mana-mana janji gagal, keseluruhan Promise.all() gagal.

2. Promise.race() untuk Janji Terpantas

Kaedah Promise.race() mengembalikan hasil janji pertama yang selesai, sama ada berjaya atau gagal.

    fetchData((data) => {
      processData(data, (processedData) => {
        saveData(processedData, (result) => {
          console.log(result);
        });
      });
    });
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Dalam contoh ini, mana-mana janji (fetchData1 atau fetchData2) yang dilengkapkan dahulu akan mempunyai hasilnya dilog masuk ke konsol.

3. Promise.allSettled() untuk Mengendalikan Semua Hasil

Kaedah Promise.allSettled() menunggu semua janji yang anda berikan berada dalam keadaan berjaya atau gagal dan kemudian selesai. Tatasusunan kemudian dikembalikan yang mempunyai keputusan setiap janji.

fetchData()
  .then(processData)
  .then(saveData)
  .then(console.log)
  .catch(console.error);
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Dalam contoh ini, Promise.allSettled() menunggu untuk kedua-dua fetchData1() dan fetchData2() selesai. Ia kemudian merekodkan status dan hasil (atau ralat) setiap janji. Dengan cara ini, anda boleh melihat apa yang berlaku dengan setiap janji, tidak kira sama ada ia berjaya atau gagal.

4.Promise.any() untuk Menyelesaikan dengan Janji Berjaya Pertama

Kaedah Promise.any() menunggu janji pertama diselesaikan dengan betul daripada senarai janji. Sekiranya sekurang-kurangnya satu janji diselesaikan, nilai akan dikembalikan oleh kaedah Promise.any(). Jika semua janji ditolak, kaedah ini akan menimbulkan ralat.

const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("Promise resolved!");
  }, 1000);
});

myPromise.then(result => console.log(result));
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Dalam contoh ini, Promise.any() menunggu janji pertama berjaya diselesaikan. Prosedur mengembalikan hasil janji pertama yang berjaya, dalam kes ini promise2dengan nilai 'Kejayaan A'. Jika semua janji ditolak, blok.catch() dilaksanakan, mengelog mesej ralat. Strategi ini bermanfaat apabila anda ingin menerima hasil janji pertama yang berjaya tanpa perlu menunggu selebihnya.

Aliran Pelaksanaan JavaScript dengan Janji (Penting)

1. Janji dalam JavaScript dijalankan dalam baris gilir microtask, yang mendapat keutamaan berbanding tugasan makro seperti setTimeout.

Berikut ialah contoh untuk menggambarkan ini:

myPromise.then(data => {
  console.log("Data received:", data);
});
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Dalam contoh ini:

  • console.log(2) berjalan dahulu kerana ia adalah operasi segerak biasa.

  • console.log (6) berjalan seterusnya kerana ia juga segerak.

  • The promise’s.then()berjalan sebelum panggilan balik setTimeout kerana promise ialah microtasks, yang mempunyai keutamaan yang lebih tinggi, justeru mencetak 3.

  • Akhir sekali, panggilan balik setTimeout berjalan, kerana ia adalah tugasan makro dan mencetak 4.

Jadi sentiasa ingat, promise’s.then()dilaksanakan sebelum panggilan balik setTimeout disebabkan keutamaan baris gilir microtask.

2. Perintah Perlaksanaan Janji dan Giliran Microtask dengan Panggilan Berbilang .then()

Dalam JavaScript, kod berjalan dalam susunan tertentu: pertama kod segerak, kemudian microtasks (seperti promises), dan akhirnya, macrotasks (likesetTimeout).

Berikut ialah satu contoh untuk menerangkan perkara ini:

    fetchData((data) => {
      processData(data, (processedData) => {
        saveData(processedData, (result) => {
          console.log(result);
        });
      });
    });
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Dalam contoh ini, kod segerak dijalankan dahulu, pengelogan 3, 6, 2, 7 dan 8. Setelah kod segerak selesai, microtasks (the.then() callbacks) diproses, log 1 dan 9. Akhir sekali, macrotasks (dari setTimeout) laksanakan mengikut urutan kelewatan mereka, log 21 (0ms) dan 13 (10ms). Ini menyerlahkan perintah pelaksanaan JavaScript: kod segerak > microtasks > tugasan makro.

3. Menyelesaikan Berbilang dan Menolak Panggilan dalam Janji: Hanya Yang Pertama Penting

Apabila anda membuat janji, panggilan pertama untuk menyelesaikan atau menolak adalah satu-satunya yang penting. Semua panggilan lain ditolak.

Berikut ialah contoh untuk menggambarkan ini:

fetchData()
  .then(processData)
  .then(saveData)
  .then(console.log)
  .catch(console.error);
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Dalam contoh ini, janji diselesaikan dengan nilai 1. Azam kedua dan panggilan tolak diabaikan kerana janji telah pun diselesaikan dengan azam pertama.

4. Merangkai Janji dan Mengendalikan Nilai dalam Panggilan .then() Sequential

Apabila anda berjanji, each.then() mengendalikan satu langkah dalam proses itu.

const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("Promise resolved!");
  }, 1000);
});

myPromise.then(result => console.log(result));
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Dalam contoh ini, Promise.resolve(1) bermula dengan nilai 1, tetapi yang pertama .then(() => 2) mengembalikan 2. .then(3) seterusnya diabaikan dan nilai 2 diteruskan. Nilai .then((value) => * 3) mendarabkan nilai dengan 3, menghasilkan 6. The .then(Promise.resolve(4)) tidak mengubah nilai dan akhirnya, .then(console. log) log 6. Ini menunjukkan cara nilai dihantar melalui rantai, dengan nilai bukan fungsi diabaikan.

5. Rantai Janji dengan Pengendalian .catch() dan .finally().

myPromise.then(data => {
  console.log("Data received:", data);
});
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Dalam contoh ini, kami merantai kaedah berbilang.then(),.catch(), dan.finally() untuk menunjukkan cara pelbagai peringkat penyelesaian janji dikendalikan. Jom pecahkan:

  • akhirnya() tidak menerima hujah:
    Blok finally() melaksanakan kod pembersihan tetapi tidak mengambil atau lulus sebarang nilai. Ia digunakan untuk memastikan kod tertentu berjalan tanpa mengira hasil janji.

  • Mengembalikan nilai dalam finally() tidak menjejaskan janji:
    Jika anda mengembalikan nilai dalam blok finally(), ia tidak menjejaskan rantai janji atau nilai akhir. Ia dilaksanakan selepas resolusi janji/penolakan tetapi tidak mengubah keputusannya.

  • Melempar ralat ke dalam finally() menyebabkan penolakan:
    Jika anda membuang ralat atau mengembalikan janji yang ditolak dalam finally(), ia akan menyebabkan rantai janji menolak dengan sebab ralat atau penolakan.

myPromise.catch(error => {
  console.error("Error:", error);
});
Salin selepas log masuk
Salin selepas log masuk

ATAU

myPromise.finally(() => {
  console.log("Cleanup tasks");
});
Salin selepas log masuk
Salin selepas log masuk
  • Tertib then() dan catch() penting .then() dan .catch() boleh digunakan dalam sebarang susunan, tetapi mereka akan sentiasa mengembalikan keadaan akhir janji. Apabila janji dikendalikan oleh .catch(), mana-mana .then() yang berikutnya akan menerima nilai akhir.

Contoh:

    fetchData((data) => {
      processData(data, (processedData) => {
        saveData(processedData, (result) => {
          console.log(result);
        });
      });
    });
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Menukar Rantai Janji kepada Async/Await

Async/wait ialah kaedah untuk menggunakan janji yang menyebabkan kod menjadi lebih seperti kod yang ditulis dalam mod segerak. Istilah yang sering digunakan ialah "gula sintaksis" kerana ia memberikan laluan yang lebih mudah dan bersih untuk melakukan kod tak segerak.

fetchData()
  .then(processData)
  .then(saveData)
  .then(console.log)
  .catch(console.error);
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Menggabungkan Janji dengan Async/Await

Anda boleh menggabungkan janji dengan async/menunggu untuk pelaksanaan selari menggunakan Promise.all().

const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("Promise resolved!");
  }, 1000);
});

myPromise.then(result => console.log(result));
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Amalan Terbaik dan Kesilapan Biasa

  • Elakkan Bersarang Dalam: Gunakan rantaian atau async/tunggu untuk memastikan kod rata dan boleh dibaca.

  • Sentiasa Tangani Ralat: Pastikan setiap rantai janji mempunyai a.catch() atau try/catch block.

  • Gunakan Perlaksanaan Selari dengan Bijak: Hanya gunakan Promise.all() apabila tugasan adalah bebas tetapi perlu diselesaikan bersama.

Kesimpulan

Janji JavaScript ialah salah satu cara terbaik untuk menangani operasi anda yang memakan masa, seperti, mendapatkan semula data pada pelayan. Ia juga membantu anda menulis kod yang lebih bersih dan lebih mudah diselenggara, dan amalan perkara yang telah anda pelajari akan melengkapkan anda untuk memanfaatkan sepenuhnya pengekodan tak segerak. Sebaik sahaja anda mendapat pengalaman praktikal dan mula mengendalikan ralat secara elegan, janji akan menjadi sebahagian besar JavaScript.

Terima kasih kerana membaca! Jika anda mendapati artikel ini membantu, sila serlahkan, tepuk tangan, tinggalkan ulasan atau hubungi saya di Twitter/X dan LinkedIn kerana ia amat dihargai dan membantu memastikan kandungan seperti ini percuma!

Atas ialah kandungan terperinci Semua yang Anda Perlu Tahu Tentang Janji JavaScript dan Cara Ia Berfungsi. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan