JavaScript vaatleri ile async await arasındaki fark nedir?


106

Ben kullanıyorum ECMAScript'i 6 ve ECMAScript 7 zaten benim uygulamalarda (Babel sayesinde) özellikleri - mobil ve web hem.

İlk adım açıkça ECMAScript 6 seviyelerine yönelikti. Pek çok eşzamansız kalıp, sözler (gerçekten ümit verici olan), üreteçler (* sembolünün neden olduğundan emin değilim) vb. Öğrendim. Bunlardan vaatler amacıma oldukça uygun geldi. Ve bunları uygulamalarımda oldukça kullanıyorum.

İşte temel bir vaadi nasıl uyguladığıma dair bir örnek / sözde kod:

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

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

Zaman geçtikçe ECMAScript 7 özellikleriyle karşılaştım ve bunlardan biri ASYNCve AWAITanahtar kelimeler / işlevler. Bunlar birlikte büyük harikalar yaratır. Verdiğim bazı sözleri ile değiştirmeye başladım async & await. Programlama stiline büyük değer katıyor gibi görünüyorlar.

Yine, işte async, await işlevimin nasıl göründüğüne dair bir sözde kod:

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

Sözdizimi hatalarını (varsa) bir kenara bırakırsak, ikisi de aynı şeyi yapıyor benim hissettiğim şey. Sözlerimin çoğunu neredeyse eşzamansız ile değiştirebildim, bekliyorlar.

Sözler benzer bir işi yaparken neden eşzamansız, ihtiyaç duyuluyor?

Eşzamansız, daha büyük bir sorunu çözmeyi mi bekliyor? Yoksa cehennemi geri aramak için farklı bir çözüm müydü?

Daha önce de söylediğim gibi, sözler ve asenkron kullanabiliyorum, aynı sorunu çözmeyi bekliyorum. Eşzamansızın çözülmeyi beklediği belirli bir şey var mı?

Ek Notlar:

React projelerimde ve Node.js modüllerimde yoğun olarak async, beklediğim ve vaatleri kullanıyorum. React özellikle erken bir kuş olmuştur ve birçok ECMAScript 6 ve ECMAScript 7 özelliğini benimsemiştir.


3
İlk kod bloğunuz, eşzamanlı bir işlem için bir söz kullanıyor gibi görünüyor. Neden bunu yapasın ki? Eşzamanlı, doğası gereği kod yazmak daha kolaydır, bu nedenle eşzamanlı bir işlemi bir söze sarmak ve şimdi eşzamansız olmaya zorlamak için çok az neden olmalıdır.
jfriend00

@ jfriend00 Evet haklısın. Kodu düzenledi. Teşekkürler.
bozzmob

2
Hala eşzamanlı işlevlerle eşzamansız araçları kullanmaya çalışıyorsunuz - şimdi her iki kod bloğunda. Neden?
jfriend00

@ jfriend00 Tamam. Burada gist.github.com/bozzmob/26d38b83dc37d1be37f5 kodum var . Lütfen bana neyi yanlış yaptığımı söyler misin?
bozzmob

10
Eşzamansız ve beklemenin ne için olduğunu anlamak için bir sürü okuma yapmanız gerekiyor gibi görünüyor. İşte bazı makaleler: JavaScript'te Async / Await'e giden uzun yol ve ES7 Async Functions ile Asenkron Kodlamayı Basitleştirme ve asenkron canavarı ES7 ile Ehlileştirme .
jfriend00

Yanıtlar:


84

Promises benzer bir işi yaparken neden eşzamansız, ihtiyaç duyuluyor? Eşzamansız, daha büyük bir sorunu çözmeyi mi bekliyor?

async/awaitbasitçe size eşzamansız kod için eşzamanlı bir his verir. Çok zarif bir sözdizimsel şeker şeklidir.

Basit sorgular ve veri manipülasyonu için Promises basit olabilir, ancak karmaşık veri manipülasyonunun olduğu ve dahil olmayan senaryolarla karşılaşırsanız, kod sadece eşzamanlı görünüyorsa (başka bir deyişle, sözdizimi kendi başına, async/awaitetrafta dolaşabilen bir "tesadüfi karmaşıklık" biçimidir ).

Bilmek istiyorsanız co, aynı tür hissi vermek için (jeneratörlerin yanında) gibi bir kitaplık kullanabilirsiniz . Bunun gibi şeyler, async/awaitnihayetinde (doğal olarak) çözen problemi çözmek için geliştirilmiştir .


1
Lütfen "tesadüfi karmaşıklığın" ne anlama geldiğini açıklar mısınız? Ayrıca, performans söz konusu olduğunda ikisi arasında bir fark yok mu?
bozzmob

@bozzmob, shaffner.us/cs/papers/tarpit.pdf <- oradaki "tesadüfi karmaşıklığı" açıklıyor. Performans sorunuza gelince, bundan şüpheliyim, özellikle V8 motoru olduğu gibi. Eminim orada bazı mükemmel testler vardır, ama bu konuda fazla endişelenmem. Gerekli olmadığında zamanınızı mikro optimizasyon için boşa harcamayın.
Josh Beam

1
Çok teşekkürler! Bu sizden aldığım harika bilgiler. Ve evet, mikro optimizasyonlara bakmayacaksınız.
bozzmob

Bu açıklamayı yararlı buldum nikgrozev.com/2015/07/14/…
mwojtera

36

Async / Await, daha karmaşık senaryolarda çok daha güzel bir sözdizimi sağlar. Özellikle, döngülerle veya try/ gibi belirli diğer yapılarla ilgili her şey catch.

Örneğin:

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

Bu örnek, sadece Promises kullanılarak çok daha karmaşık olacaktır.


Bu, aynısını anlamak için harika bir örnek. Peki performans söz konusu olduğunda ikisi arasında bir fark yok mu? Ve hangisi kodda kullanmak daha iyidir? Async Await, örneğinizi en az gördükten sonra daha iyi görünüyor.
bozzmob

1
@bozzmob: Performansta bir fark yok. Async / await kullanmakta rahatsanız, bunu tavsiye ederim. Henüz kendim kullanmıyorum çünkü aslında resmi standardın bir parçası değil.
Stephen Cleary

Evet, bunun standardın bir parçası olmadığına katılıyorum, ancak ReactJS (özel olarak yerel tepki verme) durumunda, onu kodun bazı bölümlerinde kullanmak zorunda kalıyorum. Yani, bunların yarısı vaatler ve yarısı eşzamansız bekleyenler. Ben de sana bu soruları sordum. Muhtaç bilgi için teşekkürler.
bozzmob

1
Hiç kimse kod örneklerinde dene / yakala bloğunu kullanmadığında pek çok insanın kafası karışıyor ve / veya yanlış yönlendiriliyor.
Augie Gardner

Böyle mi demek istiyorsun? const getValue = value => value || operation1().then(operation2).then(getValue);
Sharcoux

17

Promises benzer bir işi yaparken neden eşzamansız, ihtiyaç duyuluyor? Eşzamansız, daha büyük bir sorunu çözmeyi mi bekliyor? yoksa cehennemi geri aramak için farklı bir çözüm müydü? Daha önce de söylediğim gibi, Promises ve Async'i kullanabiliyorum, Aynı sorunu çözmeyi bekliyorum. Async Await'in çözdüğü belirli bir şey var mı?

Anlamanız gereken ilk şeyler async/ awaitsözdizimi sadece sözdizimsel şekerdir ve vaatleri artırmak içindir. Aslında bir asyncfonksiyonun dönüş değeri bir vaattir. async/ awaitsözdizimi bize zaman uyumsuz olarak eşzamanlı bir şekilde yazma imkanı verir. İşte bir örnek:

Söz zinciri:

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

Async işlev:

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

Yukarıdaki örnekte, awaitsözün ( fetch(url)) çözülmesini veya reddedilmesini bekler . Söz çözülürse, değer responsedeğişkende saklanır ve söz reddedilirse bir hata verir ve böylece catchbloğa girer .

async/ Kullanmanın awaitsöz zincirlemesinden daha okunaklı olabileceğini zaten görebiliyoruz . Bu, özellikle kullandığımız vaatlerin miktarı arttığında geçerlidir. Hem söz zincirleme hem de async/ awaitgeri arama cehennemi sorununu çözmek ve hangi yöntemi seçeceğiniz kişisel tercih meselesidir.


12

Artıları ve eksileri ile tam karşılaştırma.

Düz JavaScript

  • Artıları
  • Herhangi bir ek kitaplık veya teknoloji gerektirmez
  • En iyi performansı sunar
  • Üçüncü taraf kitaplıklar ile en iyi düzeyde uyumluluk sağlar
  • Geçici ve daha gelişmiş algoritmaların oluşturulmasına izin verir
  • Eksileri
  • Ekstra kod ve nispeten karmaşık algoritmalar gerektirebilir

Zaman uyumsuz (kitaplık)

  • Artıları
  • En yaygın kontrol akış modellerini basitleştirir
  • Hala geri arama tabanlı bir çözümdür
  • İyi performans
  • Eksileri
  • Harici bir bağımlılık sunar
  • Gelişmiş akışlar için hala yeterli olmayabilir

Sözler

  • Artıları
  • En yaygın kontrol akış modellerini büyük ölçüde basitleştirir
  • Sağlam hata işleme
  • ES2015 şartnamesinin bir parçası
  • OnFulfilled ve onRedject için ertelenmiş başvuruyu garanti eder
  • Eksileri
  • Geri çağırma tabanlı API'ler gerektirir
  • Küçük bir performans vuruşu sunar

Jeneratörler

  • Artıları
  • Engellemeyen API'yi engelleyici bir API gibi gösterir
  • Basit hata işleme
  • ES2015 şartnamesinin parçası
  • Eksileri
  • Tamamlayıcı bir kontrol akış kitaplığı gerektirir
  • Yine de sıralı olmayan akışları uygulamak için geri aramalar veya vaatler gerektirir
  • Jeneratör tabanlı olmayan API'ler için thunkify veya söz vermeyi gerektirir

Eşzamansız bekliyor

  • Artıları
  • Engellemeyen API'yi engelliyor gibi gösterir
  • Temiz ve sezgisel sözdizimi
  • Eksileri
  • Babel veya diğer aktarıcılar ve bugün kullanılmak üzere bazı konfigürasyonlar gerektirir

Bu nereden kopyalandı? En azından bir kısmı 136-137. Sayfalarda Node.js Design Patterns (ikinci baskı) (ISBN-10: 1785885588)
Peter Mortensen,

6

Async / await, karmaşık kontrol akışına ihtiyaç duyduğunuz durumlarda kodunuzun daha temiz ve daha okunaklı olmasına yardımcı olabilir. Ayrıca daha fazla hata ayıklama dostu kod üretir. Ve hem eşzamanlı hem de eşzamansız hataları sadece ile işlemeyi mümkün kılar try/catch.

Geçenlerde, kod örnekleriyle birlikte bazı yaygın kullanım örneklerinde async / await'in vaatlere göre avantajlarını gösteren bu yazıyı yazdım: JavaScript Async / Await Blows Blows Away'in 6 Nedeni (Eğitim)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.