2013-11-25 14 views
20

Bir vaatte beklemenin bir yolu var mı? Böylece, gerçek sonucu elde edebilmek ve söz vermenin kendisinin yerine geri dönmek için dönmeniz mümkün mü? C# anahtar kelimesinin Tasks ile nasıl çalıştığına benzer bir şey düşünüyorum.

İşte canAccess() gibi bir deyim yerine kullanabilmesi için bir söz yerine doğru veya yanlış döndüren bir yönteme neden sahip olmak istediğimin bir örneğidir. CanAccess() yöntemi $ http veya $ kaynak kullanarak bir AJAX çağrısı yapar ve sonra bir şekilde çözüme ulaşma sözü bekler.

$scope.canAccess = function(page) { 
    var resource = $resource('/api/access/:page'); 
    var result = resource.get({page: page}); 

    // how to await this and not return the promise but the real value 
    return result.canAccess; 
} 

bunu yapmak için yine de var mı: böyle bir şey olmazdı

?

Teşekkürler.

cevap

24

bu kötü bir fikir. Sana nedenini söyleyeyim. Tarayıcıda JavaScript temelde tek bir dişli canavardır. Bunu düşünmeye gel, Node.js'de de tek iş parçacığı var. Yani, uzaktan isteğin başarılı olmasını veya başarısız olmasını beklediğiniz noktada "geri dönmemek" için yaptığınız her şey, büyük olasılıkla isteğin ardından kodun yürütülmesini geciktirmek için bir çeşit döngü içerecektir. Böyle bir şey:

var semaphore = false; 
var superImportantInfo = null; 

// Make a remote request. 
$http.get('some wonderful URL for a service').then(function (results) { 
    superImportantInfo = results; 

    semaphore = true; 
}); 

while (!semaphore) { 
    // We're just waiting. 
} 

// Code we're trying to avoid running until we know the results of the URL call. 
console.log('The thing I want for lunch is... " + superImportantInfo); 

Ama bir tarayıcıda denemek ve çağrı uzun zaman alırsa, tarayıcı JavaScript kodu bir döngü içinde sıkışmış olduğunu düşünüyorum ve kullanıcının yüzü veren bir ileti açılır Kullanıcı kodunuzu durdurma şansı. böylece gibi JavaScript nedenle yapılar it:

// Make a remote request. 
$http.get('some wonderful URL for a service').then(function (results) { 
    // Code we're trying to avoid running until we know the results of the URL call. 
    console.log('The thing I want for lunch is... " + results); 
}); 

// Continue on with other code which does not need the super important info or 
// simply end our JavaScript altogether. The code inside the callback will be 
// executed later. 

geri aramasında kodu bir olayın her servis çağrı döner tetiklediği olacağını olmanın fikir. Çünkü olay, Javascript'in nasıl beğendiğini gösteriyor. JavaScript'teki zamanlayıcılar olaylardır, kullanıcı eylemleri olaylardır, veri üretme olayları göndermek ve almak için HTTP/HTTPS çağrıları da vardır. Ve kodunuzun geldiklerinde bu olaylara yanıt verecek şekilde yapılandırılması bekleniyor.

Kodunuzu, uzak hizmet çağrısı geri geldiği zamana kadar uzaktan Erişim yanlış olduğunu düşünecek şekilde yapılandıramaz ve belki de bunun gerçekten de doğru olduğunu öğrenir mi? AngularJS kodunda bunu her zaman yaparım, çünkü kullanıcıya göstermem gereken en son izinler grubunun ne olduğunu bilmiyorum çünkü bunları henüz almadım ya da görüntülenen tüm verileri almadım. önce sayfa. Gerçek veriler geri gelene kadar gösterilen varsayılan değerlerim var ve sayfa yeni verilere dayanarak yeni formuna geçiyor. AngularJS'nin iki yönlü bağlanması bunu gerçekten çok kolaylaştırıyor.

var globalRequestSync = function (pUrl, pVerbo, pCallBack) { 

     httpRequest = new XMLHttpRequest(); 
     httpRequest.onreadystatechange = function() { 

      if (httpRequest.readyState == 4 && httpRequest.status == 200) { 
       pCallBack(httpRequest.responseText); 
      } 
     } 
     httpRequest.open(pVerbo, pUrl, false); 
     httpRequest.send(null); 

    }; 
+0

Evet, çok iyi puanlar veriyorsunuz. Kodumu kesinlikle böyle yapılandırabilirim ve çok zor olmamalı. Bunu yapmanın bir yolu olsaydı daha çok merak ettim, ama benimle bunun yararından bahsetmiştin. Erişime izin vermeme fikrini beğenirim ve iki yönlü bağlayıcılığın geri kalanına bakmasına izin veririm. Teşekkürler. –

+5

İlk örnekte, 'while' ifadesinin durumunun asla doğru olmayacağını düşünmüyorum. Bunun nedeni, eşzamanlı olarak çalışacak ve HTTP isteğini hiç olmamış gibi engelleyecektir. – mightyiam

+6

Bazı durumlarda gerçekten beklemek istersiniz, bence asıl soru buydu. Bu cevap gerçekten buna cevap vermiyor. –

1

Benim yaklaşımım şu şekilde javascript nesneler OLD sahip bir işlev oluşturmak oldu. Bu, temelde sırayla çağrılacak fonksiyonlar dizisi olacak bir "talimat listesi" dediğimi göndererek çalışır.Bir şeyleri başlatmak için ilk önce() öğesini çağırmanız gerekecek, yanıt, talimat listesindeki bir sonraki öğeyle geri döndüğünde yeni bir .then() ekleyebilmeniz için dizinin kaydını tutmanız gerekir.

// instructionList is array. 
 
function syncPromises (instructionList) { 
 
    var i = 0, 
 
    defer = $q.defer(); 
 

 
    function next(i) { 
 

 
    // Each function in the instructionList needs to return a promise 
 
    instructionList[i].then(function() { 
 
     var test = instructionList[i++]; 
 
     if(test) { 
 
     next(i); 
 
     } 
 
    }); 
 
    } 
 

 
    next(i); 
 

 
    return defer.promise; 
 
}

buldum Bu bize en fazla esnekliği verdi. Bir yönerge listesi oluşturmak için işlemleri otomatik olarak vb. Yapabilir ve aynı zamanda, callee işlevindeki birçok .then() yanıt işleyicisini de ekleyebilirsiniz. Ayrıca tüm sırada gerçekleşecek birden fazla syncPromises işlevini de zincirleyebilirsiniz.

0

Geçenlerde bu sorunu vardı ve 'syncPromises' adlı bir yardımcı program yaptı:

0

Sen olamaz - herhangi bir özelliğini angular deprem olmaz, Q (söz) veya javascript bunu yapmasına izin (şu anda).

Sen ES7 olur ne zaman.

Başka bir çerçeve veya aktarıcı (bağlantılı olarak - Traceur transpiler veya Spawn öğesinde önerildiği gibi) kullanıyorsanız, yapabilirsiniz.

Kendi uygulamanızı yuvarlarsanız yapabilirsiniz!

İlgili konular