Zaman uyumlu XMLHttpRequest kullanmak için herhangi bir neden var mı?


88

Görünüşe göre çoğu kimse XMLHttpRequest ile eşzamansız istekler yapıyor, ancak açık bir şekilde eşzamanlı istekler yapabilme yeteneğinin olması, bunu yapmak için geçerli bir neden olabileceğini gösteriyor. Peki bu geçerli sebep ne olabilir?


1
Bu oldukça güzel bir soru! Cevabın çok ilginç olacağını sanmıyorum ama yine de harika bir soru. Ne olacağını görmek için eşzamanlı bir arama denediniz mi?
Tad Donaghe

3
Senkron çağrılar tarayıcıyı engeller ve bu da korkunç bir kullanıcı deneyimine yol açar. İşte benim sorum. Kullanmak için iyi bir neden düşünemedim.
Darrell Brogdon

2
Yarı ciddi cevap: belki de okuduğunuz JavaScript kitabı ne olursa olsun, asenkron isteklerden önce gelen bölümü doldurabilirsiniz.
Ben James

Şahsen, her çağrı için bir istek yazmak zorunda kalmadan birden fazla çağrıyı sunucu tarafı işlevlerine sarmak için bazı eş zamanlı ajax kullanmak istiyorum.
Paul Ishak

özellikle dahili geliştirme çerçeveleri ve araçları için kodu yerel olarak çalıştırmak.
user2800679

Yanıtlar:


26

HTML 5 standartları ilerledikçe daha popüler hale gelebileceklerini düşünüyorum. Bir web uygulamasına web çalışanlarına erişim verilirse, Jonathan'ın dediği gibi, bir isteğin diğerinden önce olmasını sağlamak için eşzamanlı isteklerde bulunmak için özel bir web çalışanı kullanan geliştiricileri öngörebilirim. Bir iş parçacığının mevcut durumu ile, istek tamamlanıncaya kadar bloke ettiği için ideal tasarımın altındadır.


16
"Web Çalışanları" demek istediğini varsayıyorum
evilpie

Bence damıtılmış nokta. UI İş Parçacığı içinde, bir iş parçacığı veya bir tür zaman uyumsuz görev oluşturun. Zaten iş parçacığı içindeyse, çoğu durumda eşitlenmiş kullanın. Konular çok daha "blok dostu"
HaMMeReD

Bu eski bir cevaptır, ancak bu yorum, HTML5'ten önce bile, istek yapmak için 2 iş parçacığı için sağlanan tarayıcılar için geçerlidir. Her ikisini de kullanmak için bir bağlantı havuzu komut dosyası yazdım, çünkü zaman uyumsuz istekte bile tek bir bağlantıyla tarayıcıyı bağlayabilirsiniz. Her ikisinin de kullanılması, hat boyunca daha fazla verinin itilmesine / çekilmesine olanak tanır; ama iirc, senkronizasyon isteklerinin hala tarayıcıya bağlı olduğunu düşünüyorum.
vol7ron

Firefox (ve muhtemelen tüm IE olmayan tarayıcılar) eşzamansız XHR zaman aşımını desteklemez. HTML5 WebWorkers zaman aşımlarını destekler. Bu nedenle, zaman aşımı davranışıyla eşzamansız XHR uygulamak için zaman aşımı ile eşitleme XHR isteğini WebWorker'a sarmak isteyebilirsiniz.
Dmitry Kaigorodov

1
-1. Bu pek bir cevap değil ve konu başlıkları hakkındaki tüm tartışma sadece konuyu karıştırıyor. Sami'nin aşağıdaki cevabı aslında çok daha iyi.
Stijn de Witt

30

Senkronize XHR'ler, kullanıcı verilerini kaydetmek için kullanışlıdır. Eğer idare ederse beforeunloadolay Kullanıcı sayfayı kapatır olarak sunucuya veri yükleyebilirsiniz.

Bu, zaman uyumsuz seçeneği kullanılarak yapıldıysa, istek tamamlanmadan sayfa kapanabilir. Bunu eşzamanlı olarak yapmak, isteğin beklenen şekilde tamamlanmasını veya başarısız olmasını sağlar.


4
Düzenlendi: Sadece tembel bir HN kullanıcısından txt attığınızın farkındayım, ancak SO'da güzelce ifade etmek için biraz zaman ayırmak takdire şayandır.
Frank Krueger

Ama aslında şimdiye kadar gördüğüm tek geçerli neden bu.
Stijn de Witt

@Frank Krueger HN Nedir?
Douglas

1
@DouglasHeld Hacker News adlı bir web sitesi news.ycombinator.com adresinde
Sami Samhuri

13

Güncelleme:

Aşağıdakiler, daha iyi eşzamansız istek işlemenin ortaya çıkmasıyla birlikte, kullanıcıların bir istek tamamlanana kadar herhangi bir şey yapmasını kasten engellemeyi amaçlamadıkça, eşzamanlı istekleri kullanmak için gerçekten bir neden olmadığını ima ediyordu - ancak teslim etmede başarısız oldu - kulağa kötü geliyor: )

Bu kulağa kötü gelse de, bir kullanıcının sayfadan ayrılmasından önce veya bir işlem gerçekleştirilmeden önce bir isteğin (veya bir dizi isteğin) gerçekleşmesinin önemli olduğu zamanlar olabilir - diğer kod yürütülmesini engellemek (örneğin, geri düğmesini engellemek) kötü tasarlanmış bir sistem için muhtemelen hataları / bakımı azaltmak ; dedi ki, onu vahşi doğada hiç görmedim ve kaçınılması gerektiğini vurguladı.

Kütüphaneler, benzeri söz , geri aramaları yoluyla süreçleri zincirleme tarafından uydurmak olarak eşzamanlılık. Bu, tarayıcıların kullanıcı için yanıt verebilirliği korumasını sağlayan (iyi UX) engelleyici olmayan olayları sipariş etme arzusunun olduğu geliştirme ihtiyaçlarının çoğuna uygundur.

As Mozilla dokümanlarında belirtildiği orada Senkronize istekleri kullanmak zorunda durumlardır; ancak, bu tür durumlarda işaretçi kullanan (IE / Safari'de mevcut değildir) bir geçici çözüm de listelenmiştir . Bu deneysel olsa da, standartların kabulüne ulaşırsa, muhtemelen eşzamanlı talep tabutuna bir çivi çakabilir.


Herhangi bir işlem benzeri işlemde veya herhangi bir işlem sırasının gerekli olduğu her yerde eşzamanlı aramalar yapmak isteyebilirsiniz.

Örneğin, bir şarkıyı çaldıktan sonra oturumunuzu kapatmak için bir olayı özelleştirmek istediğinizi varsayalım. İlk önce çıkış işlemi gerçekleşirse, şarkı asla çalınmayacaktır. Bu, isteklerin senkronize edilmesini gerektirir.

Diğer bir neden, özellikle sunucuda matematik işlemi yaparken bir WebService ile çalışırken olabilir.

Örnek: Sunucunun 1 değerinde bir değişkeni var.

 Step (1) Perform Update: add 1 to variable
 Step (2) Perform Update: set variable to the power of 3
 End Value: variable equals 8

Önce Adım (2) meydana gelirse, o zaman son değer 8 değil 2'dir; bu nedenle işlem sırası önemlidir ve senkronizasyon gereklidir.


Eşzamanlı bir aramanın yaygın bir gerçek dünya örneğinde gerekçelendirilebileceği çok az zaman vardır. Belki de girişe tıkladığınızda ve ardından sitenin bir kullanıcının oturum açmasını gerektiren bir bölümüne tıkladığınızda.

Başkalarının da söylediği gibi, tarayıcınızı bağlayacaktır, bu yüzden elinizden geldiğince ondan uzak durun.

Bununla birlikte, eşzamanlı aramalar yerine, çoğu zaman kullanıcılar şu anda yüklenmekte olan bir olayı durdurmak ve ardından başka bir işlem yapmak isterler. Bir bakıma bu senkronizasyondur, çünkü ikinci olay başlamadan önce birinci olay çıkar. Bunu yapmak için, xml bağlantı nesnesinde abort () yöntemini kullanın.


1
Bence bu doğru cevap olmalı

3
@Zack: Bu iyi bir örnek, ancak onu çağıran olaya bağlı olarak eşzamansız aramalarda muhtemelen aynısını yapabilirsiniz.
vol7ron

3
+1 Mantıksal yarış koşullarının eşzamansız sunucu isteklerinden kaynaklanabileceği geçerli bir durum var ... Ancak, çözümün eşzamanlı olması gerekmez. İstekleriniz bir Web Çalışanı tarafından işlenmedikçe, istekleri numaralandıracak bir taşıma katmanı yazmak ve ardından işlemlerin istek kimlikleri sırasına göre işlenmesini sağlamak daha iyi olacaktır.
Roy Tinker

3
-1 İşlem işleme, bir şeyin başarısız olduğu veya başarılı olduğu garantisini kullanmanız gereken mükemmel bir örnektir - yalnızca komutun eşzamanlı olması, ilk isteğin başarılı olduğu anlamına gelmez ... Bunu size söyleyen yanıta güveniyorsunuz. Bu örnekte, ikinci isteği yalnızca ilk isteğin sonuç işleyicisinden yaparsınız - bu durumda ikisi de eşzamansız olabilir.
Mathew

2
@Mathew: Bu, yalnızca işlem benzeri işleminiz kendisinden önceki eylemin sonucuna bağlıysa doğrudur. Sayfanızda yeni bir nesne (sunucudan alınan) oluşturan bir düğmeniz varsa; zaman uyumsuzsa, kullanıcı potansiyel olarak birden çok kez tıklayabilir ve birçok nesneyi döndürebilir. Eşzamanlı bir çağrı bunu engeller ve hata yapıp yapmadığına bakılmaksızın, yalnızca ilk tamamlandıktan sonra başka bir yeni nesnenin oluşturulmasına izin verir. Lütfen ifadelere dikkat edin , bilerek işlem değil, işlem gibi yaptım .
vol7ron

8

İstek kabul edilebilir bir şekilde tamamlanırken kullanıcının tarayıcısını engellemeyi düşünürseniz, eşzamanlı bir istek kullandığınızdan emin olabilirsiniz.

Amacınız isteklerin serileştirilmesiyse, bu, önceki isteğinizin onComplete geri aramasını bir sonraki satırda çalıştırarak eşzamansız istekler kullanılarak gerçekleştirilebilir.


1
Hmm, buna kayan bir pencere
eklerdim

8

Kullanıcı arayüzünü engellemenin tam olarak istenen davranış olduğu birçok gerçek dünya durumu vardır.

Birden çok alana sahip bir uygulamayı alın ve bazı alanlar, bu alanın değerini ve diğer alan değerlerini girdi olarak sağlayan bir uzak sunucuya xmlhttp çağrısıyla doğrulanmalıdır.

Senkronize modda mantık basittir, kullanıcının yaşadığı engelleme çok kısadır ve herhangi bir sorun yoktur.

Zaman uyumsuz modda, kullanıcı ilk alan doğrulanırken diğer alanların değerlerini değiştirebilir. Bu değişiklikler, henüz doğrulanmamış ilk alandaki değerlere sahip diğer xmlhttp çağrılarını tetikleyecektir. İlk doğrulama başarısız olursa ne olur? Saf karmaşa. Senkronizasyon modu kullanımdan kaldırılır ve yasaklanırsa, uygulama mantığı ele alınması gereken bir kabusa dönüşür. Temel olarak, kilitleri yönetmek için uygulamanın yeniden yazılması gerekir (örn. Doğrulama işlemleri sırasında diğer öğeleri devre dışı bırakmak). Kod karmaşıklığı muazzam bir şekilde artar. Bunu yapmamak, mantık arızasına ve sonuçta veri bozulmasına neden olabilir.

Temel olarak soru şudur: hangisi daha önemli, engellenmemiş kullanıcı arayüzü deneyimi mi yoksa veri bozulması riski mi? Cevap W3C'de değil uygulama geliştiricisinde kalmalıdır.


1
Kullanıcı etkileşimini engelleme fikrini tarayıcı iş parçacığını engellemekle karıştırdığınızı düşünüyorum. Bir asenkron çağrı sırasında, tarayıcı iş parçacığının engellenmesini gerektirmeyen herhangi bir varlık (form alanı, vb.) İş parçacığı engellendiğinde, herhangi bir mantıksal işlem olamaz ve bu, içinde olmak için sadece kötü bir durumdur; çözdüğünden çok daha fazla problem / potansiyel problem yaratır, neredeyse çözülemez.
Luke Chavers

6

Değişken konumdaki bir kaynağın, tam olarak çalışması için ilk kaynağa bağlı olan sayfadaki diğer statik kaynaklardan önce yüklenmesi gerektiğinde kullanılacak zaman uyumlu XHR istekleri için bir kullanım görebiliyorum. Aslında, böyle bir XHR isteğini kendi küçük bir alt projemde uyguluyorum, oysa JavaScript kaynakları bir dizi belirli parametreye bağlı olarak sunucudaki değişken konumlarda bulunuyor. Sonraki JavaScript kaynakları bu değişken kaynaklara dayanır ve bu tür dosyaların, diğer bağımlı dosyalar yüklenmeden önce yüklenmesinin garanti edilmesi GEREKİR, böylece uygulama bir bütün haline gelir.

Bu fikir temeli gerçekten vol7ron'un cevabını genişletiyor. İşlem tabanlı prosedürler, eşzamanlı taleplerin yapılması gereken gerçekten tek zamandır. Diğer birçok durumda, eşzamansız çağrılar, çağrıdan sonra DOM'un gerektiği gibi güncellendiği daha iyi bir alternatiftir. Kullanıcı tabanlı sistemler gibi birçok durumda, kendileri oturum açana kadar bazı özellikleri "yetkisiz kullanıcılara" kilitleyebilirsiniz. Eşzamansız aramadan sonra bu özelliklerin kilidi bir DOM güncelleme prosedürü ile açılır.

Son olarak şunu söylemeliyim ki, çoğu kişinin bu konudaki noktalarına katılıyorum: Mümkün olan her yerde, senkronize XHR isteklerinden kaçınılmalıdır, çünkü çalışma şekliyle tarayıcı senkronize aramalarla kilitlenir. Eşzamanlı istekleri uygularken, bunlar tarayıcının normalde kilitleneceği bir şekilde yapılmalıdır, örneğin HEAD bölümünde sayfa yüklemesi gerçekten gerçekleşmeden önce.


Bir eylemin başka bir eylemin sonucuna dayanması, o eylemi eşzamanlı olarak gerçekleştirmek için bir neden değildir. Yalnızca , çağıran işlev sona ermeden önce bazı eylemlerin sonucunun işlenmesi gerekiyorsa, eşzamanlı bir çağrıya ihtiyacınız var mı?
Stijn de Witt

5

2015 itibariyle masaüstü javascript uygulamaları daha popüler hale geliyor. Genellikle bu uygulamalarda yerel dosyaları yüklerken (ve bunları XHR kullanarak yüklemek tamamen geçerli bir seçenektir), yükleme hızı o kadar hızlıdır ki, kodu eşzamansız ile fazla karmaşık hale getiren çok az nokta vardır. Elbette, eşzamansızın gitmenin yolu olduğu durumlar olabilir (internetten içerik isteme, çok büyük dosyalar veya tek bir toplu işte çok sayıda dosya yükleme), ancak aksi takdirde senkronizasyon gayet iyi çalışır (ve kullanımı çok daha kolaydır) .


Aslında kendimi içinde bulduğum durum bu ve 2020. Kullanıcı arayüzünü HTTP aracılığıyla görüntüleyen bir masaüstü uygulamam var, böylece ona yerel makinede çalışan bir tarayıcıdan veya hatta ağ üzerinden erişebilirsiniz. Bu senaryolarda ağ hızlı ve güvenilirdir, bu nedenle eşzamanlı XHR istekleri yapmak, kodu basit tutmanın harika bir yoludur. Çoğu insan, eşzamansız XHR isteklerinin iş parçacığı kullanmaya benzediğini ve bunun hatalar için birçok fırsatla gerçekten karmaşık hale gelebileceğinin farkında değil.
Eric Mutta

4

jQuery, bazı durumlarda dahili olarak eşzamanlı AJAX kullanır. Komut dosyaları içeren HTML eklerken, tarayıcı bunları çalıştırmayacaktır. Komut dosyalarının manuel olarak yürütülmesi gerekir. Bu komut dosyaları tıklama işleyicileri ekleyebilir. İşleyici eklenmeden önce bir kullanıcının bir öğeyi tıkladığını ve sayfanın istendiği gibi çalışmayacağını varsayın. Bu nedenle, yarış koşullarını önlemek için, bu komut dosyalarını almak için senkronize AJAX kullanılacaktır. Eşzamanlı AJAX diğer her şeyi etkili bir şekilde engellediğinden, komut dosyalarının ve olayların doğru sırada yürütüldüğünden emin olabilir.


3

Nedeni:

Diyelim ki, kullanıcı herhangi bir etkileşim yapmadan önce yarım düzine http'nin sunucudan çeşitli verileri yüklemesi gereken bir ajax uygulamanız var.

Açıkçası, bunun yükten tetiklenmesini istiyorsunuz.

Eşzamanlı çağrılar, koda herhangi bir ek karmaşıklık olmadan bunun için çok iyi çalışır. Çok basit ve anlaşılır.

Dezavantaj:

Tek dezavantajı, tarayıcınızın tüm veriler yüklenene veya bir zaman aşımı gerçekleşene kadar kilitlenmesidir. Söz konusu ajax uygulamasına gelince, bu çok da sorun değil çünkü uygulama, tüm ilk veriler yine de yüklenene kadar kullanılmıyor.

Alternatif?

Bununla birlikte, çoğu tarayıcı, javascript bunlardan herhangi birinde meşgul olduğunda tüm pencereleri / sekmeleri kilitler ki bu aptalca bir tarayıcı tasarım problemidir - ancak sonuç olarak, muhtemelen yavaş ağlarda engelleme, kullanıcıların diğer sekmeleri kullanmasını engelliyorsa kibar değildir. ajax sayfasının yüklenmesini beklerken.

Ancak, eşzamanlı almalar zaten son tarayıcılardan kaldırılmış veya kısıtlanmış gibi görünüyor. Bunun birisinin her zaman kötü olduğuna karar vermesinden mi yoksa WC Çalışma Taslağı'nın konuyla ilgili tarayıcı yazarlarının kafasının karıştığından mı emin değilim.

http://www.w3.org/TR/2012/WD-XMLHttpRequest-20120117/#the-open-method , engelleme modunu kullanırken bir zaman aşımı ayarlamanıza izin verilmiyor gibi görünüyor (bkz. bölüm 4.7.3) . Bana karşı sezgisel görünüyor: GÇ'yi engellemek ne zaman makul bir zaman aşımı ayarlamak kibar, öyleyse neden io engellemeye izin vermeli, ancak kullanıcı tarafından belirlenmiş bir zaman aşımı olmadan?

Benim fikrim, GÇ'yi bloke etmenin bazı durumlarda hayati bir role sahip olduğu, ancak doğru şekilde uygulanması gerektiğidir. Bir tarayıcı sekmesinin veya penceresinin diğer tüm sekmeleri veya pencereleri kilitlemesi kabul edilemez olsa da, bu bir tarayıcı tasarım hatasıdır. Utanmanın hak ettiği yerde utanç. Ancak bazı durumlarda tek bir sekmenin veya pencerenin bazı durumlarda birkaç saniye boyunca yanıt vermemesi (yani, G / Ç / HTTP GET'in engellenmesi) - örneğin sayfa yüklenirken, belki de çok fazla veri olması tamamen kabul edilebilir. herhangi bir şey yapılmadan önce yapılması gerekiyor. Bazen uygun şekilde uygulanan engelleme kodu, bunu yapmanın en temiz yoludur.

Elbette bu durumda eşdeğer işlev, eşzamansız http alır kullanılarak elde edilebilir, ancak ne tür saçma bir rutin gereklidir?

Sanırım bu satırlarda bir şeyler deneyeceğim:

Belge yüklenirken aşağıdakileri yapın: 1: 0 olarak başlatılan 6 genel "Bitti" bayrak değişkeni ayarlayın. 2: 6 arka plan alımının tümünü gerçekleştirin (Sıranın önemli olmadığını varsayarak)

Daha sonra, 6 http alımının her biri için tamamlama geri aramaları, ilgili "Bitti" bayraklarını ayarlayacaktır. Ayrıca, her geri arama, 6 HTTP'nin tamamının tamamlanıp tamamlanmadığını görmek için yapılan diğer tüm bayrakları kontrol eder. Tamamlanması gereken son geri çağırma, diğerlerinin tamamlandığını gördükten sonra, daha sonra her şeyi ayarlayacak olan GERÇEK init işlevini çağıracaktı, şimdi verilerin tümü getirildi.

Getirme sırası önemliyse veya web sunucusu aynı anda birden fazla isteği kabul edemiyorsa, şuna benzer bir şeye ihtiyacınız olacaktır:

Onload () 'da ilk http get başlatılır. Geri aramada, ikincisi başlatılacaktı. Geri aramada, üçüncü - ve benzeri, her geri arama bir sonraki HTTP GET'i başlatır. Sonuncusu geri döndüğünde, gerçek init () rutini çağırırdı.


2

Üretim kodunda eşzamanlı bir arama yaparsanız ne olur?

Gökyüzü düşüyor.

Hayır cidden, kullanıcı kilitli bir tarayıcıdan hoşlanmaz.


2
Soru şu: "neden XMLHTTPREQUEST ile yapmalı" değil, "neden senkronizasyon aramaları yapmalı ya da yapmamalı"
Itay Moav -Malimovka

1
Makul bir zaman aşımı eklerseniz, bu sorun olmaz.
Greg

1
Senkronize aramaların kullanım durumlarını sorar ... Bunların dezavantajları için değil (şimdiye kadar hepimiz bunları biliyoruz ...)
Stijn de Witt

ne kullanıcısı? tüm kullanıcılar aynı mı? mühendisler yerel olarak test etmeye ne dersiniz? ... çok az gecikmeyle dosya sistemindeki dosyalara erişiliyor mu ????
user2800679

2

Kullanıcı adının halihazırda var olup olmadığını kontrol ederken bir kullanıcı adını doğrulamak için kullanıyorum.

Bunu eşzamansız olarak yapmanın daha iyi olacağını biliyorum, ancak o zaman bu özel doğrulama kuralı için farklı bir kod kullanmalıyım. Daha iyi açıklarım. Doğrulama kurulumum, verilerin geçerli olmasına bağlı olarak doğru veya yanlış döndüren bazı doğrulama işlevlerini kullanıyor.

İşlevin geri dönmesi gerektiğinden, eşzamansız teknikleri kullanamıyorum, bu yüzden bunu eşzamanlı yapıyorum ve sunucunun yeterince fark edilmeyecek kadar çabuk yanıt vermesini umuyorum. Bir AJAX geri araması kullandıysam, yürütmenin geri kalanını diğer doğrulama yöntemlerinden farklı şekilde ele almam gerekirdi.


Böyle bir senaryodaki bir püf noktası, doğrulama işlevinin bir bayrağı kontrol etmesine (şu şekilde başlar false) ve sunucu yanıt verdiğinde bunu doğru veya yanlış olarak ayarlamasına izin vermektir . alan değiştiğinde bayrağı sıfırlar ve sunucuyu yeniden ararsınız.
Stijn de Witt

2

Bazen başkalarına bağlı bir eyleminiz olur. Örneğin, B eylemi yalnızca A bitmişse başlatılabilir. Senkronize yaklaşım genellikle yarış koşullarından kaçınmak için kullanılır . Bazen senkronize bir çağrı kullanmak daha basit bir uygulamadır ve daha sonra birbirine bağlı olan asenkron çağrılarınızın her durumunu kontrol etmek için karmaşık mantık oluşturmaktır.

Bu yaklaşımla ilgili sorun, kullanıcının tarayıcısını eylem bitene kadar (istek geri dönene, bitene, yüklenene kadar, vb.) "Engellemenizdir". Bu yüzden onu kullanırken dikkatli olun.


Soru, "neden bunu XMLHTTPREQUEST ile yapalım" değil, "neden senkronizasyon çağrıları yapalım"
Itay Moav -Malimovka

Yazarın kendisi " Eşzamanlı aramalar tarayıcıyı bloke ederek korkunç bir kullanıcı deneyimine yol açar " diyor . bir yorumda, bu yüzden bu ileti dizisindeki herkes "eşzamanlı çağrılar" yaklaşımı için başvurdu. Yazarın ne demek istediğini gerçekten kesin olarak söyleyemiyorsanız, sorunun bu gerçek anlayışını neden aldınız?
GmonC

2

Kod geliştirirken eşzamanlı çağrılar kullanıyorum - istek sunucuya gidip gelirken yaptığınız her şey bir hatanın nedenini belirsizleştirebilir.

Çalıştığı zaman, eşzamansız yapıyorum, ancak bir durdurma zamanlayıcısı ve başarısız geri aramaları eklemeye çalışıyorum, çünkü asla bilemezsiniz ...


2

SYNC ve ASYNC: Aralarındaki fark nedir?

Temelde şuna indirgeniyor:

console.info('Hello, World!');
doSomething(function handleResult(result) {
    console.info('Got result!');
});
console.info('Goodbye cruel world!');

Ne zaman doSomethingbir senkron bu yazacaktı:

Hello, World!
Got result!
Goodbye cruel world!

Bunun aksine, doSomethingbir asenkron , bu yazacaktı:

Hello, World!
Goodbye cruel world!
Got result!

İşlev doSomething, çalışmasını eşzamansız olarak yaptığı için, iş tamamlanmadan önce geri döner. Yani sonucu sadece baskıdan sonra alıyoruzGoodbye cruel world!

Bir eşzamansız çağrının sonucuna bağlıysak, bağlı kodu geri aramaya yerleştirmemiz gerekir:

console.info('Hello, World!');
doSomething(function handleResult(result) {
    console.info('Got result!');
    if (result === 'good') {
        console.info('I feel great!');
    }
    else {
        console.info('Goodbye cruel world!');
    }
});

Bu nedenle, 2 veya üç şeyin sırayla olması gerektiği gerçeği, bunları eşzamanlı olarak yapmak için bir neden değildir (ancak senkronizasyon kodu çoğu insan için daha kolaydır).

NEDEN SENKRON XMLHTTPREQUEST KULLANILMALIDIR?

Çağrılan işlev tamamlanmadan sonuca ihtiyaç duyduğunuz bazı durumlar vardır. Şu senaryoyu düşünün:

function lives(name) {
    return (name !== 'Elvis');
}
console.info('Elvis ' + (lives('Elvis') ? 'lives!' : 'has left the building...');

Çağıran kod ( console.infohat) üzerinde herhangi bir kontrolümüz olmadığını livesve sunucuya sormak için işlevi değiştirmemiz gerektiğini varsayalım ... Sunucuya içeriden zaman uyumsuz bir istek yapıp livesyine de livestamamlanmadan yanıtımızı alabilmemizin bir yolu yok . Dönmek isteyip bilemeyiz Yani trueyafalse . Sonucu işlev tamamlanmadan almanın tek yolu eşzamanlı bir istek yapmaktır.

Sami SamhuriCevabında belirtildiği gibi , işleviniz sona ermeden önce sunucu isteğinize bir yanıt vermeniz gerekebilecek çok gerçek bir senaryo onbeforeunload, uygulamanızın pencere kapanmadan önce çalışacak olan son işlevi olduğu için olaydır.

ARAMALARI SENKLEME İHTİYACIM YOK, ANCAK ONLARI KOLAY OLDUĞU İÇİN HER ZAMAN KULLANIRIM

Lütfen yapma. Eşzamanlı çağrılar tarayıcınızı kilitler ve uygulamanın yanıt vermemesini sağlar. Fakat sen haklısın. Zaman uyumsuz kod daha zordur. Bununla birlikte başa çıkmayı çok daha kolay hale getirmenin bir yolu var. Senkronizasyon kodu kadar kolay değil, ancak yaklaşıyor: Promise s.

İşte bir örnek: Üçüncü bir kod segmenti çalışmadan önce iki eşzamansız çağrının her ikisi de başarıyla tamamlanmalıdır:

var carRented = rentCar().then(function(car){
  gasStation.refuel(car);
});

var hotelBooked = bookHotel().then(function(reservation) {
  reservation.confirm();
});

Promise.all([carRented, hotelBooked]).then(function(){
  // At this point our car is rented and our hotel booked.
  goOnHoliday();
});

İşte nasıl uygulayacağınız bookHotel:

function bookHotel() {
  return new Promise(function(resolve, reject){
    if (roomsAvailable()) {
      var reservation = reserveRoom();
      resolve(reservation);
    }
    else {
      reject(new Error('Could not book a reservation. No rooms available.'));
    }
  });
}

Ayrıca bkz: Promises ile Daha İyi JavaScript Yazın .


1
"Lütfen yapmayın. Eşzamanlı aramalar tarayıcınızı kilitler ve uygulamanın yanıt vermemesini sağlar" Bu her zaman bir sorun değildir. Localhost'u test ettiğinizi ve bir geliştirici olduğunuzu hayal edin.
user2800679

2

XMLHttpRequestgeleneksel olarak zaman uyumsuz istekler için kullanılır. Bazen (hata ayıklama veya belirli iş mantığı için) bir sayfadaki eşzamansız çağrıların tümünü / birkaçını eşitlemek için değiştirmek istersiniz.

JS kodunuzdaki her şeyi değiştirmeden yapmak istersiniz. Eşzamansız / eşitleme bayrağı size bu yeteneği sağlar ve doğru tasarlanırsa, kodunuzda yalnızca bir satırı değiştirmeniz / varyürütme sırasında bir satırın değerini değiştirmeniz gerekir .



1

Az önce, forEach (ve bir for döngüsü) kullanılarak arka arkaya çağrılan url'lerin bir listesi için zaman uyumsuz isteklerin kalan isteklerin iptal edilmesine neden olduğu bir durum yaşadım. Senkronize geçtim ve amaçlandığı gibi çalışıyorlar.


1

Senkronize HTTP isteklerini kullanmak, mobil reklamcılık işinde yaygın bir uygulamadır.

Uygulamalar oluşturan şirketler ("Yayıncılar" olarak da bilinir) genellikle gelir elde etmek için reklam yayınlar. Bunun için uygulamalarına reklam SDK'ları yüklerler. Çoğu var (MoPub, Ogury, TapJob, AppNext, Google Ads AdMob).

Bu SDK'lar, reklamları bir web görünümünde sunacak.

Bir kullanıcıya bir reklam sunarken , özellikle sorunsuz bir deneyim olmalıdır video oynatırken . Hiçbir anda arabelleğe alma veya yükleme olmamalıdır.

Bunu çözmek precachingiçin kullanılır. Medyanın (resim / videolar / vb.) Web görünümünün arka planında eşzamanlı olarak yüklendiği yer.

Neden eşzamansız yapmıyorsunuz?

  1. Bu, küresel olarak kabul edilen bir standardın parçasıdır
  2. SDK onload, reklamın kullanıcıya sunulmaya "hazır" olduğunu bilmek için etkinliği dinler

Eşzamanlı XMLHttpRequest'lerin kullanımdan kaldırılmasıyla birlikte , reklam işi büyük olasılıkla gelecekte standardı başka bir yol belirlenemedikçe değiştirmeye zorlanacaktır.


0

Eşzamanlı XHR, dahili araç ve / veya çerçeve geliştirme (üretim dışı) için çok yararlı olabilir. Örneğin, ilk erişimde eşzamanlı olarak bir kod kitaplığı yüklemek istediğinizi düşünün, örneğin:

get draw() 
{
    if (!_draw)
    {
       let file;
       switch(config.option)
       {
           case 'svg':
              file = 'svgdraw.js';
              break;
           case 'canvas':
              file = 'canvasdraw.js';
              break;
           default:
              file = 'webgldraw.js';
       }

       var request = new XMLHttpRequest();
       request.open('GET', file, false);
       request.send(null);
       _draw = eval(request.responseText);
    }

    return _draw;
}

Kendinizi bir tizzy'ye sokmadan ve kötülük değerlendirmelerini körü körüne geri getirmeden önce, bunun yalnızca yerel testler için olduğunu unutmayın. Üretim derlemeleri için _draw zaten ayarlanmış olacaktır.

Dolayısıyla kodunuz şöyle görünebilir:

foo.drawLib.draw.something(); //loaded on demand

Bu, XHR senkronizasyonu olmadan yapılması imkansız olan bir şeye sadece bir örnektir. Bu kitaplığı önden yükleyebilir, evet veya söz / geri arama yapabilirsiniz, ancak XHR senkronizasyonu olmadan kütüphaneyi eşzamanlı olarak yükleyemezsiniz. Bu tür bir şeyin kodunuzu ne kadar temizleyebileceğini düşünün ...

Takımlar ve çerçeveler (yerel olarak çalışan) için bununla yapabileceklerinizin sınırları yalnızca hayal gücünüzle sınırlıdır. Yine de, JavaScript dünyasında hayal gücü biraz sınırlı görünüyor.


-1

İşte iyi bir neden. Bir http isteği yapmak istedim, sonra sonuca bağlı olarak, bir girdi türü = dosyası için tıklayın () öğesini çağırın. Eşzamansız xhr veya getirme ile bu mümkün değildir. Geri arama, "kullanıcı eylemi" bağlamını kaybeder, bu nedenle çağrı click () yok sayılır. Senkronize xhr pastırmamı kurtardı.

onclick(event){
    //here I can, but I don't want to.
    //document.getElementById("myFileInput").click();
    fetch("Validate.aspx", { method : "POST", body: formData, credentials: "include" })
    .then((response)=>response.json())
    .then(function (validResult) {
        if (validResult.success) {
            //here, I can't.
            document.getElementById("myFileInput").click();
        }
    });
}

bir değişikliğe kaydet
Es Noguera
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.