Rumah > Artikel > hujung hadapan web > JavaScript Asynchronous: Promises vs. Async/Await in Details
Pengaturcaraan tak segerak adalah penting dalam pembangunan web moden, terutamanya dalam JavaScript. Secara tradisinya, bahasa pengaturcaraan melaksanakan kod secara berurutan dari atas ke bawah. Walau bagaimanapun, model pelaksanaan segerak ini boleh membawa kepada ketidakcekapan, terutamanya apabila berurusan dengan operasi yang memakan masa seperti mengambil data daripada pelayan, mengakses fail atau melakukan pengiraan yang kompleks. Pengaturcaraan tak segerak menangani cabaran ini dengan membenarkan proses tertentu berjalan secara bebas daripada utas pelaksanaan utama, dengan itu mempertingkatkan responsif dan prestasi aplikasi web.
Secara semula jadi satu-benang, JavaScript menggunakan pengaturcaraan tak segerak untuk mengurus operasi yang sebaliknya akan menyekat urutan pelaksanaan sehingga selesai. Ini dicapai melalui ciri seperti panggil balik, janji dan sintaks async/menunggu, yang membantu mengendalikan operasi yang sememangnya tidak pasti dalam masa penyiapannya. Kepentingan menguasai pengaturcaraan tak segerak dalam JavaScript tidak boleh dilebih-lebihkan. Ia membolehkan pembangun mencipta pengalaman web yang lebih lancar, lebih pantas dan lebih interaktif. Apabila tapak web dan aplikasi web menjadi semakin kompleks dan dipacu data, pengendalian operasi tak segerak dengan berkesan adalah penting untuk mengekalkan prestasi dan menyediakan pengalaman pengguna yang lancar.
Pada dasarnya, pengaturcaraan tak segerak bukan sahaja mengoptimumkan prestasi aplikasi web dengan menghalang sekatan utas utama tetapi juga menyumbang dengan ketara kepada kebolehskalaan dan kebolehselenggaraan pangkalan kod. Sambil kita mendalami subjek ini, kita akan meneroka mekanisme dan corak yang disediakan JavaScript untuk mengendalikan operasi tak segerak dan sebab ia amat diperlukan dalam kit alat pembangun web moden.
Bayangkan membuat pesanan anda di kaunter di kedai kopi yang sibuk. Daripada menunggu minuman anda disediakan, anda duduk dan menyemak imbas majalah. Sementara itu, barista menjalankan pesanan anda. Setelah kopi anda siap, barista memanggil anda untuk mengambilnya. Senario ini serupa dengan cara operasi tak segerak berfungsi dalam JavaScript.
Dalam JavaScript, operasi tak segerak adalah seperti menghantar pesanan anda ke dapur; anda tidak perlu berdiri dan menunggu tukang masak selesai. Anda boleh terus membaca buku anda, berbual dengan rakan atau menikmati muzik di kafe. Anda akan dimaklumkan sebaik sahaja pesanan anda sedia, dan anda boleh menikmati hidangan anda. Begitu juga, JavaScript tak segerak membenarkan tugas seperti panggilan API atau operasi fail dijalankan di latar belakang. Seperti anda di kafe, program utama tidak disekat; ia terus berjalan dan bertindak balas kepada input atau tindakan pengguna lain.
Panggilan API: Ini seperti memesan makanan daripada perkhidmatan penghantaran sambil menonton filem. Anda tidak menjeda filem untuk menunggu makanan; anda terus menonton, dan apabila loceng pintu berbunyi, anda mendapat makanan anda. Dalam pembangunan web, meminta pelayan untuk data berfungsi dengan cara yang sama. Anda meminta data dan terus berinteraksi dengan tapak, dan ia dipaparkan kepada anda sebaik sahaja data tiba.
fetch('https://jsonplaceholder.typicode.com/todos/1') .then(response => response.json()) // Convert the response to JSON .then(data => console.log(data)) // Log the data .catch(error => console.error('Error:', error)); // Handle any errors
Operasi Fail: Ini sama seperti menghantar dokumen untuk dicetak pada pencetak semasa anda mengemas meja anda. Anda tidak perlu berdiri di tepi pencetak menunggu semua dokumen anda; anda terus melakukan tugas anda yang lain. Begitu juga, operasi fail dalam JavaScript (terutamanya pada platform seperti Node.js) membolehkan anda memulakan operasi membaca atau menulis fail dan kemudian beralih kepada tugas lain, menerima pemberitahuan apabila operasi selesai.
const fs = require('fs'); fs.readFile('example.txt', 'utf8', (err, data) => { if (err) { console.error('Error reading the file:', err); return; } console.log(data); // Log the contents of the file });
Pemasa dan Kelewatan: Menggunakan setTimeout() atau setInterval() dalam JavaScript adalah seperti menetapkan pemasa ketuhar semasa membakar kek. Anda menetapkan pemasa dan biarkan ketuhar melakukan tugasnya semasa anda menyiapkan beberapa pembekuan. Pemasa tidak menghentikan aktiviti anda yang lain; ia hanya memaklumkan anda bila perlu mengambil langkah seterusnya.
setTimeout(() => { console.log('This message appears after 2 seconds!'); }, 2000);
Pendengar Acara: Bayangkan menyediakan penderia gerakan di taman anda yang membunyikan loceng apabila ia mengesan pergerakan. Beginilah cara pendengar acara berfungsi. Anda menyediakannya untuk menonton acara tertentu (seperti klik atau ketukan kekunci), dan ia menjalankan fungsi yang berkaitan sebagai tindak balas tanpa mengganggu operasi lain aplikasi anda.
document.getElementById('myButton').addEventListener('click', () => { console.log('Button was clicked!'); });
Imagine you're at a carnival and just tossed a ring towards a bottle, aiming to hook it. At that moment, three outcomes are possible: the ring lands perfectly (success), misses entirely (failure), or is still spinning in the air (pending). In JavaScript, this scenario is analogous to a Promise. A Promise is an object that represents the eventual completion or failure of an asynchronous operation. It’s like making a bet on whether the ring will land.
Pending: The Promise is initially in the "pending" state. It's uncertain, like the ring spinning in the air.
Fulfilled: If the asynchronous operation completes successfully, the Promise is "fulfilled." Think of this as the ring landing on the bottle.
Rejected: If the operation fails or encounters an error, the Promise is "rejected." This is akin to the ring missing the target.
Here is how you can create a promise for the above example:
const ringToss = new Promise((resolve, reject) => { let hasLanded = Math.random() > 0.5; // Random chance of success if (hasLanded) { resolve('You won a prize!'); // Fulfill the promise } else { reject('Try again!'); // Reject the promise } }); console.log(ringToss); // Logs the Promise object showing its state
Now that you've tossed the ring, you need strategies to handle the outcome, whether a win or a miss.
.then(): This method is used when the promise is fulfilled. It’s like claiming your prize at the carnival booth.
.catch(): This handles rejections or errors. It’s the equivalent of deciding what to do after you miss the ring toss.
.finally(): This method is for code that runs regardless of the outcome, similar to walking away from the booth after winning or losing.
Chaining promises is like playing several carnival games in a row. You must complete one game to receive a token that lets you play the next.
enterBooth() .then(token => playGameOne(token)) .then(prize => tradeForToken(prize)) .then(token => playGameTwo(token)) .then(prize => console.log(`You won: ${prize}`)) .catch(error => console.error('Game error:', error));
In the example of chaining promises above, each step represents a sequential operation, each dependent on the success of the previous one. Here’s what happens in each step:
enterBooth(): This is likely the initial step where you "enter" the asynchronous operation. Imagine it as signing up or logging into an online service. This function returns a Promise.
.then(token => playGameOne(token)): Once you successfully enter, you receive a token. This token is then used to play the first game. This step is also a Promise, dependent on obtaining the token from enterBooth().
.then(prize => tradeForToken(prize)): If you win the first game, you receive a prize. This prize must be traded for another token to continue to the next game. This trading action is another asynchronous operation that returns a Promise.
.then(token => playGameTwo(token)): With the new token, you can play the second game. Again, this step is only possible if the previous step of trading the prize for a token is successful.
.then(prize => console.log(You won: ${prize})): If the second game is won, you will receive another prize. This prize is logged to the console, indicating the successful end of this promise chain.
You might be wondering when the .catch block comes into play. The .catch() block is invoked if any of the Promises in the chain fail or are rejected. This could happen if:
*You failed to enter the booth (enterBooth() fails).
*Any game along the way (playGameOne() or playGameTwo()) does not result in a prize.
*The prize cannot be traded for a token.
In any of these scenarios, the .catch() block catches the error, logs it or takes other corrective action. This prevents the error from stopping the entire script and allows for graceful error handling.
Choosing between Promises and Async/Await largely depends on your project's specific needs. Async/Await might be the clearer choice for complex sequences of dependent operations due to its straightforward syntax and ease of error handling. Conversely, when dealing with multiple, simultaneous operations that do not depend on each other, utilizing Promises with techniques like Promise.all can significantly enhance performance. Both tools are essential in a JavaScript developer’s toolkit, empowering you to write more efficient, cleaner code.
Atas ialah kandungan terperinci JavaScript Asynchronous: Promises vs. Async/Await in Details. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!