2010-02-03 6 views
5

Şu anda senkronize olması gereken bir Ajax çağrım var. Ancak, bu Ajax çağrısı yürütülürken, arama geri dönene kadar tarayıcı arabirimi donar. Zaman aşımı durumunda, bu tarayıcı bir significant period of time için donabilir.Bir Javascript döngüsünde iken güncellenecek bir tarayıcı penceresi almak mümkün mü?

Kullanıcı arayüzünü yenilemek için tarayıcıya (herhangi bir tarayıcıya) sahip olmanın, herhangi bir Javascript'i çalıştırmanın bir yolu var mı? İdeal olarak, kullanıcı arayüzünün yenilemesine izin veren window.update() gibi bir komut olurdu. Bu mümkün olurdu

, o zaman ben böyle bir şeyle senkron AJAX çağrısı yerini alabilir:

obj = do_async_ajax_call(); 
while (!obj.hasReturned()) { 
    window.update(); 
} 
// synchronous call can resume 

Ben setTimeout kullanın veya geri aramasında bir işlevi devam ettiremezsiniz nedeni olduğunu (hepsi birbirine bağlıdır çok fazla devlet değişken vardır ve long_function() akış aksi şekilde devam ettirilmesi olurdu): yürütme akışı kesintiye edilemez

function long_function() { 
    // lots of code, reads/writes variable 'a', 'b', ... 
    if (sync_call_is_true()) { 
    // lots of code, reads/writes variable 'a', 'b', ... 
    } else { 
    // lots of code, reads/writes variable 'a', 'b', ... 
    } 
    // lots of code, reads/writes variable 'a', 'b', ... 
    return calculated_value; 
} 
+2

Aramanın neden senkronize olması gerekiyor? –

+1

Tüm arama kodunu gönderir misiniz? Bu muhtemelen basitleştirilebilir ve ihtiyacınız olanı desteklemek için XHR işlevlerini kullanabilir (jQuery bir seçenek değilse ve daha temizse bile). Eğer bir seçenek de yoksa, iĢlevi 'do_sync_jax_call();' –

cevap

3

yapmak geri arama çoğaltılabilir Eşzamansız istek ve geri arama kullanın. Basitleştirilmiş bir örnek olacaktır:

obj = do_async_ajax_call(function (data, success) 
{ 
    if (success) 
    { 
     // continue... 
    } 
}); 

function do_async_ajax_call(callback) 
{ 
    var xhr = new XMLHttpRequest(); 
    xhr.open("GET", "http://mysite.com", true); 
    xhr.onreadystatechange = function() 
    { 
     if (xhr.readyState == 4 && xhr.status == 200) 
      callback(xhr.responseXML, true); 
     else if (xhr.readyState == 4) 
      callback(null, false); 
    } 
    xhr.send(); 
} 

Eğer ajax talep eden işleve parametre olarak bir anonim işlev geçiyoruz Bu şekilde. Ajax tamamlandığında, geçirilen işlev ona verilen responseXML ile çağrılır. Bu arada, tarayıcı, arama tamamlanana kadar olağan bir şey yapmakta özgürdü. Buradan, kodunuzun geri kalanı devam ediyor.

+0

olarak yeniden adlandırmanızı rica ediyorum. Bu normalde yeterli olur, ancak iĢlem akışını (soruda güncellendiği gibi) bölemem. Şimdi başka bir yaklaşım deniyorum ... – jevon

+0

Bu * her zaman * bölünmesi mümkün; Bu, CPS dönüşümüdür (“devam eden geçiş stilini” arar; devam parametresi geri aranmanızdır). Yerel durum değişkenleriniz geri arama işlevinde basitçe kapatılır. Döngü tekrarlı çağrılar olur. Asıldığın zaman o kadar da zor ya da belirsiz değil. –

+0

Her zaman mümkün olduğunu kabul ediyorum, ancak bu durumda en iyi çözüm değildi (çok fazla durum değişkeni vardı!) :) Sonunda, müşteriyi güncellemek için önceki geri aramaların (veya normal sunucu sorgulaması) sonucunu kullandım Gerektiğinde senkronize çağrının önbelleğe alınmış değeri ile birlikte, bu yüzden Ajax'ı çağırmaya gerek yoktur. – jevon

0

aramanın dinlen ve koyun geri aramada sonuç geri geldiğinde çağrılır. Bunu yapmanın tamamen imkansız olduğundan şüphe ediyorum. Eğer çağrı koymak gerekir Herhangi mantık

0

asenkron ajax setTimeout sonra alıp Bir ile Senkronize isteği değiştirmeniz gerekiyor (callback'inde tetiklediği) parçalar halinde işleme çalışmalarını

0

Tek j iğne JavaScript mevcut. Bu nedenle, bir gelgit döngüsündeyken UI'yi güncelleyemezsiniz. Ancak, Firefox 3.5'dan başlayarak, web çalışanı olarak adlandırılan çok iş parçacıklı JavaScripts için ek destek var. Web çalışanları sayfanın kullanıcı arayüzünü etkileyemez, ancak kullanıcı arayüzünün güncellemelerini de engellemezler. İşçiler de Chrome ve Safari tarafından destekleniyor.
Sorun şu ki, AJAX aramanızı arka plan iş parçacığına taşıdığınızda ve yürütme işleminin tamamlanmasını bekleseniz bile, kullanıcılar düğmelere basabilir ve kullanıcı arabiriminizdeki değerleri değiştirebilir (ve anladığım kadarıyla, bu sizin kaçınmaya çalışmak). Kullanıcıların herhangi bir değişikliğe yol açmasını önlemek için önerebileceğim tek şey, tüm kullanıcı arayüzünü engelleyecek ve web çağrısı geri gelene kadar sayfa ile etkileşime izin vermeyecek bir çeviricidir.

+0

Kullanıcıların sayfala etkileşimde bulunup bulunmadığını (ve etkileşimin sıraya girmiş olduğunu) umursamıyorum; ancak şu anda, Firefox'ta senkronize bir Ajax araması yürütülürken, tüm tarayıcı donuyor. Bunu önlemek istediğim şey bu. – jevon