Bu makalede, senkronize JavaScript ile ilgili sorunları ve bunları asenkron geri çağırma, vaat ve async / await teknikleriyle nasıl çözebileceğimizi keşfediyoruz .
Son yıllarda JavaScript'in bu alanda nasıl geliştiğini keşfetmek için örneklerle tek tek üç yoldan geçiyoruz. Bununla birlikte, bu tekniklere bakmadan önce, eşzamanlı ve eşzamansız kod arasındaki farka bakalım.
JavaScript, tek iş parçacıklı bir programlama dilidir, bu da aynı anda yalnızca bir şeyin olabileceği anlamına gelir. Tek bir iş parçacığı, kod hakkında yazmayı ve muhakemeyi basitleştirirken, bunun bazı dezavantajları da vardır.
Ağ üzerinden bir kaynak getirmek gibi uzun süren bir görev yaptığımızı hayal edin. Şimdi, kaynak indirilene kadar tarayıcıyı engelliyoruz. Bu, kötü bir kullanıcı deneyimine yol açabilir ve kullanıcının sayfamızdan ayrılmasına neden olabilir.
Kodu eşzamanlı olarak çalıştırdığımızda , bir sonraki göreve geçmeden önce bitmesini bekleriz. Her işlem işlenirken başka hiçbir şey olamaz - oluşturma duraklatılır.
Açıklamak için biraz kod yazalım:
Bu kod beklendiği gibi yürütülür.
1. "Başlat" ı günlüğe kaydederiz.
2. "logFunction" da günlüğe kaydedilen işlevi yürütürüz.
3. "End" i günlüğe kaydederiz .
Bu nedenle, senkronize görevler birbirlerinden haberdar olmalı ve sırayla yürütülmelidir.
Eşzamansız JavaScript işte burada devreye giriyor. Eşzamansız JavaScript kullanarak, ana iş parçacığını engellemeden uzun süreli görevleri gerçekleştirebiliriz. Bir şeyi eşzamansız olarak yürüttüğümüzde , bitmeden başka bir göreve geçebiliriz.
Olay döngü JavaScript'in asenkron programlama arkasında sır değildir. JavaScript, tüm işlemleri tek bir iş parçacığı üzerinde yürütür, ancak birkaç akıllı veri yapısı kullanmak bize çoklu iş parçacığı yanılsamasını verir. Aşağıdaki örneklerde başlık altında neler olduğunu anlamak istiyorsanız, eşzamanlılık modeli ve olay döngüsü hakkında daha fazla bilgi okumalısınız .
Bu sefer
setTimeout()kodunu çalıştırmadan önce belirli bir milisaniye beklememize izin veren başka bir örnek yapalım :
"Zaman aşımına uğradı" nın "End" ten önce günlüğe kaydedilmesini bekliyor muydunuz?
Kodun çalıştırılmasını engellemiyoruz, bunun yerine devam ediyor ve
setTimeoutbir saniye sonra kodu çalıştırmak için geri dönüyoruz .
Başka bir örneğe bakalım. Sunucudan bir görüntü aldığımızda, sonucu hemen döndüremeyiz. Bu, aşağıdakilerin işe yaramayacağı anlamına gelir:
let response = fetch('myImage.png'); // fetch is asynchronous let blob = response.blob();
Bunu asenkron kodla nasıl çözeceğimize bakalım.
Eşzamansız programlamaya yönelik bu yaklaşım, yavaş performans gösteren eylemlerin fazladan bir argüman, bir geri arama işlevi almasını sağlamaktır . Yavaş eylem bittiğinde, sonuçla birlikte geri arama işlevi çağrılır.
Örnek olarak,
setTimeoutişlev bir işlevi çağırmadan önce belirli bir milisaniye kadar bekler. Arka ucu şu şekilde çağırmadan yavaş eşzamansız görevleri simüle edebiliriz:
setTimeout(() => console.log('One second later.'), 1000);
Birkaç seviye derine inen iç içe geçmiş geri aramalara bazen geri arama cehennemi denir . Her yeni geri arama düzeyi, kodu anlamayı ve sürdürmeyi daha zor hale getirir. Geri aramayı kullanmak bugünlerde yaygın değil, ancak şanssız kalırsak onları eski kod tabanlarında bulabiliriz.
Ardından, modern JavaScript'in bu sorunu nasıl çözmeye çalıştığına bakacağız.
ES6 ile tanıtılan sözler, JavaScript'teki eşzamansız işlemlerle başa çıkmanın yeni bir yoludur. Bir söz gelecekte bir değer doğurabileceğini bir nesnedir. Tıpkı gerçek hayatta olduğu gibi, sözün tutulup tutulmayacağını bilmiyoruz ve sonucu beklerken vaat edilen nesneyi yer tutucu olarak kullanıyoruz.
const promise = new Promise();
Promise yapıcısı, biri başarı (çözümleme) ve biri başarısızlık (reddetme) için olmak üzere iki parametreli bir geri arama olmak üzere bir bağımsız değişken alır. Bir sözü yerine getirmişse çözmemiz ya da başarısız olursa reddetmemiz gerekir:
JavaScript'teki bir söz, gerçek hayattaki bir söze benzer. Ya tutulacak (yerine getirilecek) ya da olmayacak (reddedilecek).
Bir söz şunlar olabilir:
resolve()aradı.
reject()aradı.
Bir söz yaratalım ve çözelim:
Sözü yerine getirmenin yerine getirilmiş bir durumla sonuçlandığını görebiliriz .
Şimdi bir söz oluşturduğumuza göre, onu nasıl kullanacağımızı görelim.
resolveVeya
rejectişlevleri tarafından iletilen değere erişmek için kullanabiliriz
then(). İki isteğe bağlı argüman alır, çözülmüş bir vaka için bir geri arama ve reddedilen bir vaka için bir geri arama.
Bu durumda, şu
then()yöntemi kullanarak çözülmüş değerini elde ederiz :
Bir söz yalnızca bir kez çözülebilir veya reddedilebilir.
Yana
then()döner yeni bir vaat, o zincirleme edilebilir. Eşzamanlı kod gibi, zincirleme de seri olarak çalışan bir sırayla sonuçlanır.
Bazı verileri aldığımız bu basitleştirilmiş örneği düşünün:
fetch(url) .then(processData) .then(saveData) .catch(handleErrors);
Zincirleme olasılığı, geri aramalara kıyasla Promises kullanmanın avantajlarından biridir.
Bir söz reddedildiğinde, kontrol en yakın reddetme işleyicisine atlar.
catch()Hemen sonra olmak zorunda değildir, bunun yerine bir ya da birden sonra görünebilir
then().
Tüm söz zincirlerini bir
catch().
Sözler, genellikle bir ağ üzerinden veri alırken veya JavaScript'te diğer eşzamansız programlama türlerini yaparken kullanılır ve modern JavaScript'in ayrılmaz bir parçası haline gelmiştir.
Şimdi bir göz atalım
async/await.
Eşzamansız işlevler ve await anahtar sözcüğü , ECMAScript 2017 ile yapılan yeni eklemeler, vaatlerin üstüne sözdizimsel şeker işlevi görerek, sahne arkasında eşzamansız görevler gerçekleştirirken eşzamanlı görünen kod yazmamızı sağlar.
Önce
asyncanahtar kelimeye sahibiz . Zaman uyumsuz bir işleve dönüştürmek için bir işlev bildiriminin önüne koyarız .
async function getData(url) {}
Eşzamansız işlevler , sözlü kodu eşzamanlıymış gibi yazmamızı sağlar, ancak yürütme iş parçacığını engellemeden ve bunun yerine eşzamansız olarak çalışır.
Ancak,
asynctek başına sihri gerçekleştirmez. Bir sonraki adım,
awaitişlevin içindeki anahtar kelimeyi kullanmaktır .
Eşzamansız işlevlerin gerçek avantajı, bunları
awaitanahtar sözcükle birleştirdiğinizde ortaya çıkar . Await, yalnızca eşzamansız bir blok içinde kullanılabilir; burada JavaScript, bir sözün bir sonuç döndürmesini bekleyin.
let value = await promise
Bir vaatten sonucu elde etmenin daha zarif bir sözdizimi
promise.then().
fetch()
XMLHttpRequest(XHR) ile benzer ağ isteklerinde bulunmamızı sağlar . Temel fark, Getirme API'sinin geri aramalardan kaçınarak daha basit ve daha temiz bir API sağlayan vaatler kullanmasıdır.
En basit kullanımı
fetch()bir argüman alır - kaynağa giden yol - ve yanıtı içeren bir söz verir.
async getData(url) { const data = await fetch(url); return data; }
Şimdi, işlevimizi hazırladık. Unutmayın, bir söz verdiğinden,
then()değeri elde etmek için kullanmamız gerekir .
getData(url).then((data) => console.log(data));
getData(url).then(console.log);
Eğer
await promisereddedilir, bir vardı sadece sanki hata atar
throwo çizgisinde ifade. Bu
try/catchhatayı, bir hatanın atıldığı normal kodda olduğu gibi kullanarak yakalayabiliriz .
Buna sahip
try/catchdeğilsek, zaman uyumsuz işlevin çağrılmasıyla oluşturulan söz reddedilir. Bunu
catch()halletmek için ekleyebiliriz :
getData(url).catch(alert);
Test amacıyla, verileri yerel olarak kullanılabilir hale getirerek başlamak genellikle iyi bir fikirdir. Bunu verilerle bir json dosyası oluşturarak yapabiliriz .
fetch()Verileri ondan almak için kullanabildiğimizden , tıpkı bir uzak aramada yaptığımız gibi, URL'yi yerelden uzakya değiştirmek kolaydır.
Getirmeyi doğrudan dosya sisteminde kullanamıyoruz, bu nedenle dosyamızı sunmak için bir web sunucusu çalıştırmamız gerekiyor.
Makinemizde bir web sunucumuz yoksa, basit, sıfır konfigürasyonlu komut satırı http-sunucusunu kullanabiliriz . İhtiyacınız node.js makinenizde yüklü. Npx , Düğüm paketlerini yürütmek için bir araçtır ve onu sunucumuzu çalıştırmak için kullanabiliriz:
npx http-server
Artık dosyayı sunduğumuza göre, gerçek kodlamaya başlayabiliriz.
Öncelikle
data.jsonverileri JSON formatında kaydedebileceğimiz bir dosya oluşturuyoruz . Ardından, verileri yerel json dosyasından almak için bir eşzamansız işlev yazıyoruz
getData():
Getirmenin yanıtı, gerçek JSON değil, bir HTTP yanıtıdır. JSON gövde içeriğini yanıttan çıkarmak için
json()yöntemi kullanıyoruz. Kodu çalıştırmak, verileri yerel dosyadan alır.
Hemen tamamlanmayan bir kodumuz olduğunda, devam etmeden önce bitmesini beklememiz gerekir. Eşzamansız JavaScript'in devreye girdiği yer burasıdır. Eşzamanlı ve eşzamansız JavaScript arasındaki farkları ve bunu ilk kez geri aramalarla çözmeye nasıl çalıştığımızı inceledik.
Ardından, vaatleri ve geri aramalarla karşılaştığımız bazı sorunları nasıl çözdüklerini öğrendik. Sözler, genellikle bir ağ üzerinden veri getirilirken veya JavaScript'te diğer eşzamansız programlama türleri yapılırken kullanılır. Modern JavaScript'in ayrılmaz bir parçası haline geldiler ve bu nedenle JavaScript geliştiricilerinin ustalaşması önemlidir.
Async / await, okunması ve bakımı daha basit olan zaman uyumsuz kod yazmanın güzel, basitleştirilmiş bir yolunu sağlar.
asyncAnahtar kelime fonksiyonları doğrudan değerini dönen yerine bir söz dönmek olduğunu söyler.
awaitAnahtar kelime sadece bir söz bir sonuç dönünceye kadar JavaScript bekleyin hale getiren bir zaman uyumsuz bloğunun içinde kullanılabilir.
Umarım bunu okuduktan sonra, eşzamansız JavaScript'i ve onu uygulamak için kullanabileceğimiz farklı teknikleri daha iyi anlarsınız.
Bilinç nedir? Yüzyıllardır filozofların ve bilim adamlarının kafasını karıştıran bir sorudur. Bazıları bunun bedenlerimizden bağımsız olarak gerçekten anlayamadığımız geçici bir şey olduğunu söylüyor.
Yıllık ortalama 154 bin dolar maaş ve istikrarlı iş büyümesi ile şimdi blok zinciri geliştirmeyi öğrenmek için ideal zaman. Blok zinciri teknolojilerini oluşturmak ve geliştirmek için blok zinciri geliştiricileri, bilgisayar ağı, kriptografi, algoritmalar ve veri yapıları dahil olmak üzere çeşitli beceriler kullanır.
Bu blogda, İngilizce'ye yaklaşımımı nasıl ve neden değiştirmeye karar verdiğimi ve yaptığım bazı etkinliklerden para kazanarak bir yıldan kısa bir sürede fakir bir B1'den başlayarak B2 seviyesine nasıl geldiğimi tartışacağım. İçindekiler Okulda örnek bir öğrenci olmasam da İngilizce öğrenmek her zaman kültürel geçmişime eklemek istediğim bir şeydi.
Bu ay tüm yeni abonelerimize ve yazarlarımıza sıcak bir karşılama; sürülerinizde ortaya çıkıyorsunuz ve bunun için size teşekkür ediyoruz. Burada harika bir topluluk oluşturuyoruz ve yorumlarınızı ve makalelerinizi okumak harika.
"Tren kazası" kelimesinden nefret ediyorum. İnsanlar kendi ahlaki pusulalarında teselli bulur ve bunu yaparken kendilerini yargıda bulunurken bulurlar.
Angular uygulamanızın bazı bölümlerinin neden hala yavaş olduğunu merak ediyor musunuz? Bu makale, uygulama performansınızı nasıl artırabileceğinizi size gösterecek. Angular uygulamalarınızı gecikmeli ve yavaş buluyor ancak bunları nasıl geliştireceğiniz konusunda hiçbir fikriniz yok mu? Uygulamanızın performansını artırmanın yaklaşık 5 yolunu öğrenmek için doğrudan bu makaleye dalalım.