2015-03-31 20 views
15

vaat ederken vaatler kullanarak bir süre döngü uygulamaya çalışıyorum.Bluebird kullanarak döngü

Burada ana hatlarıyla belirtilen yöntem işe yarayacak gibi görünüyor. http://blog.victorquinn.com/javascript-promise-while-loop yap Bu döküm gibi anti-desen ve deprecated yöntemleri kullanmak ve erteleme gibi görünüyor bu

var Promise = require('bluebird'); 

var promiseWhile = function(condition, action) { 
    var resolver = Promise.defer(); 

    var loop = function() { 
     if (!condition()) return resolver.resolve(); 
     return Promise.cast(action()) 
      .then(loop) 
      .catch(resolver.reject); 
    }; 

    process.nextTick(loop); 

    return resolver.promise; 
}; 

gibi bir işlev kullanır.

Bunu gerçekleştirmenin daha iyi veya daha modern bir yolu olduğunu bilen var mı?

Teşekkür

+0

Eğer deyişle açıklayabilir Gerçekten başarmak istediğiniz şeyi: toplamını döndürür koşulu ile Döngü? Meşgul bekleme döngüsünün Javascript'te korkunç bir şey olduğunu unutmayın. Sıkı bir döngüde tekrar tekrar aramaktan ziyade bir tür olay işleyicisini kullanmak daha mantıklıdır. Ve, ne eylem() yapar? Belki bunu nasıl kullanacağınıza dair bir örnek gösterilsin mi? – jfriend00

cevap

19

castresolve için tercüme edilebilir. defer, indeed not be used olmalıdır.

Döngününüzü, yalnızca Promise.resolve(undefined) numaralı ilke üzerine then çağrıları zincirleme ve yerleştirme yoluyla oluşturabilirsiniz. İşte

function promiseWhile(predicate, action, value) { 
    return Promise.resolve(value).then(predicate).then(function(condition) { 
     if (condition) 
      return promiseWhile(predicate, action, action()); 
    }); 
} 

, hem predicate ve action sözlerini iade edebilir.

var Continue = {}; // empty object serves as unique value 
var again = _ => Continue; 

var repeat = fn => Promise.try(fn, again) 
    .then(val => val === Continue && repeat(fn) || val); 

Örnek 1: benzer uygulamalar da olacağını orijinal işlevine Closer Correct way to write loops for promise. de bakabilirsiniz için

function promiseWhile(predicate, action) { 
    function loop() { 
     if (!predicate()) return; 
     return Promise.resolve(action()).then(loop); 
    } 
    return Promise.resolve().then(loop); 
} 
+0

Bir işlevi kabul etmek için 'loop' işlevini değiştirebilir ve sonra 'action' işlevi tarafından döndürülen son değeri almak için, yüklem yanlış olduğunda çözümleyebilirsiniz. – Sami

+0

@Sami: Evet, [bağlantılı sorudaki cevap] (http://stackoverflow.com/a/24660323/1048572) örneğin bunu yapar. Ancak bu cevabı her zaman 'undefined' – Bergi

+0

olarak çözen OPs fonksiyonuna yakın tutmak istedim, 'promiseWhile' eyleminizin bir örneğini gösterebilir misiniz? Gerçekten nasıl kullanılacağı konusunda şaşkın. –

3

Ben mola simüle ve onunla devam etmek daha kolay onun bu uygulamayı tercih durur rasgele durdurmak para çevirme verilirse% 90 olasılık sonuçları wit: ya kaynak ya da hedef bir hatayı

repeat(again => 
    source.read() 
    .then(data => destination.write(data)) 
    .then(again) 

Örnek 2, h a 0

var blah = repeat(again => 
    Promise.delay(1000) 
    .then(_ => console.log("Hello")) 
    .then(_ => flipCoin(0.9) && again() || "blah")); 

Örnek 3:

repeat(again => { 
    if (sum < 100) 
    return fetchValue() 
     .then(val => sum += val) 
     .then(again)); 
    else return sum; 
}) 
+1

Muhtemelen benzersiz bir değer için 'Symbol' kullanırdım, ancak başka bir şey iyi görünüyor :) –

+0

tanrı düşünme benji –