Apa perbedaan antara janji JavaScript dan async await?

97

Saya telah menggunakan fitur ECMAScript 6 dan ECMAScript 7 (berkat Babel) di aplikasi saya - baik seluler maupun web.

Langkah pertama yang jelas adalah ECMAScript 6 level. Saya belajar banyak pola async, promise (yang benar-benar menjanjikan), generator (tidak yakin mengapa simbol *), dll. Dari semua ini, promise cukup sesuai untuk tujuan saya. Dan saya sudah cukup sering menggunakannya dalam aplikasi saya.

Berikut adalah contoh / pseudocode tentang bagaimana saya menerapkan janji dasar-

var myPromise = new Promise(
    function (resolve,reject) {
      var x = MyDataStore(myObj);
      resolve(x);
    });

myPromise.then(
  function (x) {
    init(x);
});

Seiring berjalannya waktu, saya menemukan fitur ECMAScript 7, dan salah satunya adalah ASYNCdan AWAITkata kunci / fungsi. Ini dalam hubungannya melakukan keajaiban besar. Saya sudah mulai mengganti beberapa janji saya dengan async & await. Mereka tampaknya memberi nilai tambah yang besar pada gaya pemrograman.

Sekali lagi, berikut adalah pseudocode tentang bagaimana fungsi async, await saya terlihat-

async function myAsyncFunction (myObj) {
    var x = new MyDataStore(myObj);
    return await x.init();
}
var returnVal = await myAsyncFunction(obj);

Mengesampingkan kesalahan sintaks (jika ada), keduanya melakukan hal yang persis sama adalah apa yang saya rasakan. Saya hampir bisa mengganti sebagian besar janji saya dengan async, tunggu.

Mengapa async, menunggu diperlukan saat promise melakukan pekerjaan serupa?

Apakah asinkron, menunggu menyelesaikan masalah yang lebih besar? Atau apakah itu hanya solusi berbeda untuk menelepon balik neraka?

Seperti yang saya katakan sebelumnya, saya dapat menggunakan promise dan async, menunggu untuk menyelesaikan masalah yang sama. Apakah ada hal khusus yang menunggu penyelesaian async?

Catatan tambahan:

Saya telah menggunakan async, menunggu dan janji dalam proyek React dan modul Node.js saya secara ekstensif. React khususnya telah menjadi yang pertama dan mengadopsi banyak fitur ECMAScript 6 dan ECMAScript 7.

bozzmob.dll
sumber
3
Blok kode pertama Anda tampaknya menggunakan janji untuk operasi sinkron. Kenapa kamu ingin melakukan itu? Synchronous, pada dasarnya, lebih mudah untuk menulis kode sehingga seharusnya ada sedikit alasan untuk menggabungkan operasi sinkron menjadi sebuah promise dan memaksanya menjadi async.
jfriend00
@ jfriend00 Ya, Anda benar. Mengedit kode. Terima kasih.
bozzmob
2
Anda masih mencoba menggunakan alat asinkron dengan fungsi sinkron - sekarang di kedua blok kode. Mengapa?
jfriend00
@ jfriend. Di sini saya memiliki kode gist.github.com/bozzmob/26d38b83dc37d1be37f5 . Tolong bisakah Anda memberi tahu saya apa yang saya lakukan salah?
bozzmob
10
Sepertinya Anda hanya perlu banyak membaca untuk memahami apa itu async dan a waiting. Berikut beberapa artikelnya: Jalan panjang menuju Async / Await dalam JavaScript dan Menyederhanakan Pengodean Asinkron dengan Fungsi Asinkron ES7 dan Menjinakkan monster asinkron dengan ES7 .
jfriend00

Jawaban:

75

Mengapa async, await diperlukan saat Promises melakukan tugas serupa? Apakah asinkron, menunggu menyelesaikan masalah yang lebih besar?

async/awaithanya memberi Anda nuansa sinkron ke kode asinkron. Ini adalah bentuk gula sintaksis yang sangat elegan.

Untuk kueri sederhana dan manipulasi data, Promises bisa jadi sederhana, tetapi jika Anda mengalami skenario di mana ada manipulasi data yang kompleks dan yang tidak terlibat, lebih mudah untuk memahami apa yang terjadi jika kode hanya terlihat seolah-olah sinkron (dengan kata lain, sintaks itu sendiri adalah suatu bentuk "kompleksitas insidental" yang async/awaitdapat disiasati).

Jika Anda tertarik untuk mengetahuinya, Anda dapat menggunakan library like co(bersama generator) untuk memberikan kesan yang sama. Hal-hal seperti ini telah dikembangkan untuk memecahkan masalah yang async/awaitakhirnya terpecahkan (secara native).

Josh Beam
sumber
Tolong bisakah Anda menjelaskan apa yang dimaksud dengan "kerumitan insidental"? Juga, dalam hal kinerja, tidak ada perbedaan antara keduanya?
bozzmob
@bozzmob, shaffner.us/cs/papers/tarpit.pdf <- dia menjelaskan "kompleksitas insidental" di sana. Mengenai pertanyaan kinerja Anda, saya ragu, terutama dengan mesin V8 yang seperti itu. Saya yakin ada beberapa tes kinerja di luar sana, tetapi saya tidak akan terlalu khawatir tentang itu. Jangan buang waktu Anda untuk pengoptimalan mikro jika tidak diperlukan.
Josh Beam
1
Terima kasih banyak! Ini adalah beberapa informasi hebat yang saya dapatkan dari Anda. Dan ya, tidak akan melihat pengoptimalan mikro.
bozzmob
Saya menemukan penjelasan ini bermanfaat nikgrozev.com/2015/07/14/…
mwojtera
33

Async / Await menyediakan sintaks yang jauh lebih baik dalam skenario yang lebih kompleks. Secara khusus, apa pun yang berhubungan dengan loop atau konstruksi tertentu lainnya seperti try/ catch.

Sebagai contoh:

while (!value) {
  const intermediate = await operation1();
  value = await operation2(intermediate);
}

Contoh ini akan jauh lebih berbelit-belit hanya dengan menggunakan Promises.

Stephen Cleary
sumber
Ini adalah contoh yang bagus untuk memahami hal yang sama. Jadi, kalau bicara soal performa, tidak ada perbedaan antara keduanya? Dan mana yang lebih baik untuk digunakan dalam kode? Async Await tampaknya lebih baik setelah melihat setidaknya contoh Anda.
bozzmob
1
@ Bozzmob: Tidak ada perbedaan dalam performa. Jika Anda merasa nyaman menggunakan async / await, maka saya akan merekomendasikannya. Saya sendiri belum menggunakannya karena sebenarnya bukan bagian dari standar resmi.
Stephen Cleary
Ya, saya setuju ini bukan bagian dari standar, tetapi, dalam kasus ReactJS (bereaksi asli secara khusus), saya agak terpaksa menggunakannya di beberapa bagian kode. Jadi, setengahnya adalah janji dan setengahnya lagi async-menunggu. Jadi, saya menanyakan pertanyaan-pertanyaan itu. Terima kasih atas informasi yang dibutuhkan.
bozzmob
1
Saya pikir banyak orang bingung dan / atau disesatkan ketika tidak ada yang menggunakan blok coba / tangkap dalam sampel kode mereka.
Augie Gardner
Maksudmu seperti itu? const getValue = value => value || operation1().then(operation2).then(getValue);
Sharcoux
13

Mengapa async, await diperlukan saat Promises melakukan tugas serupa? Apakah asinkron, menunggu menyelesaikan masalah yang lebih besar? atau apakah itu hanya solusi yang berbeda untuk menelepon balik neraka? Seperti yang saya katakan sebelumnya, saya dapat menggunakan Promises dan Async, Menunggu untuk menyelesaikan masalah yang sama. Apakah ada sesuatu yang spesifik yang diselesaikan Async Await?

Hal pertama yang harus Anda pahami bahwa async/ awaitsintaks hanyalah gula sintaksis yang dimaksudkan untuk menambah janji. Faktanya, nilai kembali dari suatu asyncfungsi adalah sebuah janji. async/ awaitsyntax memberi kita kemungkinan untuk menulis asynchronous secara sinkron. Berikut ini contohnya:

Perangkaian janji:

function logFetch(url) {
  return fetch(url)
    .then(response => response.text())
    .then(text => {
      console.log(text);
    }).catch(err => {
      console.error('fetch failed', err);
    });
}

Async fungsi:

async function logFetch(url) {
  try {
    const response = await fetch(url);
    console.log(await response.text());
  }
  catch (err) {
    console.log('fetch failed', err);
  }
}

Dalam contoh di atas, awaitmenunggu promise ( fetch(url)) diselesaikan atau ditolak. Jika promise diselesaikan, nilainya disimpan dalam responsevariabel, dan jika promise ditolak, hal itu akan menimbulkan kesalahan dan karenanya memasuki catchblok.

Kita sudah bisa melihat bahwa menggunakan async/ awaitmungkin lebih mudah dibaca daripada rantai janji. Ini terutama benar ketika jumlah janji yang kita gunakan meningkat. Baik rantai janji dan async/ awaitmemecahkan masalah neraka panggilan balik dan metode mana yang Anda pilih adalah masalah preferensi pribadi.

Willem van der Veen
sumber
7

Perbandingan penuh dengan pro dan kontra.

JavaScript biasa

  • Pro
  • Tidak memerlukan perpustakaan atau teknologi tambahan
  • Menawarkan kinerja terbaik
  • Memberikan tingkat kompatibilitas terbaik dengan pustaka pihak ketiga
  • Memungkinkan pembuatan algoritme ad hoc dan algoritme yang lebih canggih
  • Kontra
  • Mungkin memerlukan kode tambahan dan algoritme yang relatif kompleks

Asinkron (pustaka)

  • Pro
  • Menyederhanakan pola aliran kontrol yang paling umum
  • Masih merupakan solusi berbasis panggilan balik
  • Penampilan yang bagus
  • Kontra
  • Memperkenalkan ketergantungan eksternal
  • Mungkin masih belum cukup untuk aliran lanjutan

Janji

  • Pro
  • Sangat menyederhanakan pola aliran kontrol yang paling umum
  • Penanganan error yang kuat
  • Bagian dari spesifikasi ES2015
  • Menjamin permintaan yang ditangguhkan dari onFulfilled dan onRejected
  • Kontra
  • Membutuhkan promisify callback-based APIs
  • Memperkenalkan hit kinerja kecil

Generator

  • Pro
  • Membuat API non-pemblokiran terlihat seperti yang memblokir
  • Menyederhanakan penanganan error
  • Bagian dari spesifikasi ES2015
  • Kontra
  • Membutuhkan perpustakaan aliran kontrol komplementer
  • Masih membutuhkan callback atau janji untuk mengimplementasikan aliran non-sekuensial
  • Memerlukan API berbasis nongenerator thunkify atau promisify

Async menunggu

  • Pro
  • Menjadikan API non-pemblokiran terlihat seperti memblokir
  • Sintaks yang bersih dan intuitif
  • Kontra
  • Membutuhkan Babel atau transpiler lain dan beberapa konfigurasi untuk digunakan saat ini
Johnny
sumber
Dari mana ini disalin? Setidaknya beberapa di antaranya ada di halaman 136-137 dalam buku Pola Desain Node.js (edisi kedua) (ISBN-10: 1785885588)
Peter Mortensen
6

Async / await dapat membantu membuat kode Anda lebih bersih dan lebih mudah dibaca jika Anda memerlukan aliran kontrol yang rumit. Ini juga menghasilkan kode yang lebih ramah debug. Dan memungkinkan untuk menangani kesalahan sinkron dan asinkron hanya dengan try/catch.

Saya baru-baru ini menulis posting ini yang menunjukkan keuntungan dari async / await over promise dalam beberapa kasus penggunaan umum dengan contoh kode: 6 Alasan Mengapa JavaScript Async / Await Blows Promises Away (Tutorial)

gafi
sumber