2016-04-01 18 views
0

Sözlerimi düzgün bir şekilde yürütmek için özyinelememi nasıl yazmalıyım? Promise.all ile çalıştım (Array.map (function() {})); Bu adımların bir sırayla çalıştırılması gerektiği için ihtiyaçlara uymuyor. Ben here bulundu için özel bir söz denedim, ama aynı zamanda sorunları var.Javascript sözlü yineleme ve zincirleme

için söz: Bu ile

var promiseFor = (function(condition, action, value) { 
    var promise = new Promise(function(resolve, reject) { 
     if(!condition(value)) { 
      return; 
     } 
     return action(value).then(promiseFor.bind(null, condition, action)); 
    }); 
    return promise; 
}); 

sorun değil düzgün bitirmek için döngüye devam dönmeden, en derin özyinelemeli çağrı durdurmak gibi görünüyor olmasıdır. Örneğin

: PHP bir kodu şöyle:

function loopThrough($source) { 
    foreach($source as $value) { 
     if($value == "single") { 
      //do action 
     } else if($value == "array") { 
      loopThrough($value); 
     } 
    } 
} 

i geçmesi durumunda "tek" bir klasör yapısı ve diyelim dosya anlamına gelir, bu tüm dosyaları yazdırılır. Ama benim kullandığım söz, ilk çıkmazda durur.

DÜZENLEME: Yine de aynı şeyle ilgili herhangi bir şeyde yardımcı olup olmayacağını görmek için bluebird eklendi. İşte, 3 dizilerine sahip akım döngüsü kodu

var runSequence = (function(sequence, params) { 
    return Promise.each(sequence, function(action) { 
     console.log(action['Rusiavimas'] + ' - ' + action['Veiksmas']); 
     if(params.ButtonIndex && params.ButtonIndex != action['ButtonIndex']) { 
      return Promise.resolve(); 
     } 

     if(action['Veiksmas'].charAt(0) == '@') { 
      var act = action['Veiksmas']; 
      var actName = act.substr(0, act.indexOf(':')).trim(); 
      var actArg = act.substr(act.indexOf(':')+1).trim(); 

      /* This one is the code that figures out what to do and 
       also calls this function to execute a sub-sequence. */ 
      return executeAction(actName, actArg, params); 
     } else { 
      sendRequest('runQuery', action['Veiksmas']); 
     } 
    }); 
}); 

olduğu her 5 eylemlerin oluşan. Birinci ve ikinci dizi, üçüncü eylem olarak bir sonraki diziye sahiptir. İşte Benim elde ettiğim sonuç (sayılar anlamına gelen dizisi): bir sonraki diziyi girer ve olması gerektiği gibi devam eder ancak üçüncüsü tamamlandıktan sonra, ikinci sırasını ve bitiş tekrar başlayacaktır görebileceğiniz gibi

1 - @PirmasVeiksmas 
1 - @AntrasVeiksmas 
1 - @Veiksmas: list_two 
2 - @PirmasVeiksmas 
2 - @AntrasVeiksmas 
2 - @Veiksmas: list_three 
3 - @PirmasVeiksmas 
3 - @AntrasVeiksmas 
3 - @TreciasVeiksmas 
3 - @KetvirtasVeiksmas 
3 - @PenktasVeiksmas 

İlk olanla. Fakat özyinelemede ilk çıkmaz tarafa çarptığı anda durur.

EDIT2: Codepen link

Çıktı olmalıdır: o verir, böylece

fa1 
second 
sa1 
third 
ta1 
ta2 
ta3 
sa3 
fa3 
+0

bu php kodu senkronize değil mi? – dandavis

+0

@dandavis no, bu sadece bir örnekti, neden ilk vaat ucuna isabet ettiğinde vaat zincirinin durmasının neden olduğunu anlayamıyorum ve bir önceki için devam etmek için bir adım (tekrarlama) yapması gerek. – IntoDEV

+0

Lütfen her zaman kodu bulduğunuz yeri belirtin - yazarın özelliklerini kullanın ve buraya bir bağlantı ekleyin! Btw, [işte orijinal] (http://stackoverflow.com/a/24660323/1048572) (aynı zamanda hataya sahip değil) – Bergi

cevap

0

Yani bu codepen kodla ilgili sorunları giderir şimdi ne oluyor görsel gösterimi ile var ne Codepen örneği İstediğiniz çıktı. Bir dizideki eylemlerin bir demet Koşu

var sequences = { 
    first: ['fa1', 'second', 'fa3'], 
    second: ['sa1', 'third', 'sa3'], 
    third: ['ta1', 'ta2', 'ta3'] 
}; 

var loopThrough = (function(sequence) { 
    return sequence.forEach(function(action) { 
    return doAction(action); 
    }); 
}); 

var doAction = (function(action) { 
    var promise = new Promise(function(resolve, reject) { 
    console.log(action); 
    if(action == 'second' || action == 'third') { 
     //recurse into sub-sequence 
     return loopThrough(sequences[action]); 
    } else { 
     //do something here 
    } 
    resolve(); 
    }); 
    return promise; 
}); 

loopThrough(sequences.first); 
1

.reduce() yerine .map() ile yapılabilir.

İşte bir örnek: Eğer doğru ihtiyaçlarınızı anlasalardı

// Helper function that creates a Promise that resolves after a second 
 
const delay = (value) => new Promise(resolve => setTimeout(() => resolve(value), 1000)); 
 

 
const arr = [1, 2, 3, 4, 5]; 
 

 
// concurrent resolution with `.map()` and `Promise.all()` 
 
Promise.all(arr.map(delay)) 
 
    .then(console.log.bind(console)); // [1, 2, 3, 4, 5] after a second. 
 

 
// sequential resolution with `.reduce()` 
 

 
arr.reduce((promise, current) => 
 
      promise 
 
       .then(() => delay(current)) 
 
       .then(console.log.bind(console)), 
 
      Promise.resolve()); 
 
// second wait, 1, second wait, 2...

, tam olarak o, sen sırayla Promises çalıştırmak için bulduğumuz yol Promise özyinelemeye oluyor gerekmez. .reduce(), daha basit bir şekilde size yardımcı olabilir. Eğer tüm sonuçları erişmek istiyorsanız, biraz daha fazla çalışma yapmak gerektiğini

Promise.resolve() 
    .then(() => delay(1)) 
    .then(console.log.bind(console)) 
    .then(() => delay(2)) 
    .then(console.log.bind(console)) 
    .then(() => delay(3)) 
    .then(console.log.bind(console)) 
    .then(() => delay(4)) 
    .then(console.log.bind(console)) 
    .then(() => delay(5)) 
    .then(console.log.bind(console)) 

Dikkat edin:

azaltma süreci içine [1,2,3,4,5] döner.Ama bu okuyucu için bir egzersiz olarak bırakacağım :)

+0

Teşekkürler, ama ben zaten başka bir stackoverflow sorusu ile bu sorunu çözdüm, problem çözülmüş 3.x'e taşındığından beri jQuery 2.x ile ilgili sorunlar yaşadım ortaya çıkıyor. Ben onları bağımsız tutmak için sözleri jQuery kullanmıyordum, ama sadece benim kodda jQuery sahip olmak birkaç şey berbat. Edit: Eğer ilgileniyorsanız burada [link] (http://stackoverflow.com/questions/36426786/why-does-this-ajax-request-with-promises-break-the-code-as-running -it-olmayan) – IntoDEV