Soru Bir es6 vaat zincirini nasıl eşzamanlı olarak çözersiniz?


Bir söz verdiğim kütüphaneden bir fonksiyonum var. Bu işlevi birkaç kez çalıştırmam gerekiyor, ancak her yineleme bir önceki göreve kadar beklemeli.

Benim varsayımım bunu yapabilmemdi:

promiseReturner(1)
  .then(promiseReturner(2)
  .then(promiseReturner(3)
  .then(...)

Bir döngü kullanılarak basitleştirilebilir:

var p = Promise.resolve();
for (var i=1; i<=10; i++) {
  p = p.then(promiseReturner(i));
}

Ancak, bunu yaptığımda, zincirdeki her söz bir diğerinin ardından değil, aynı anda yürütülür. .then() ima ediyor gibi görünüyor. Açıkçası ben sözler hakkında temel bir şey eksik - ama bazı öğreticiler ve blog mesajları okuduktan sonra hala kayboldum.

İşte benim girişimi göstermek için yazdığım bir kod yazarı..


18
2018-02-23 20:43


Menşei


does promiseReturner(n) bir söz ver, ya da bir söz geri dönüşü işlevi mi? - Bergi


Cevaplar:


"Döngülemez" çözümünüz de çalışmaz. Geçmek zorundasın fonksiyon için .thensöz değil:

var p = Promise.resolve();
for (var i=1; i<=10; i++) {
  (function(i) {
      p = p.then(function() {
          return promiseReturner(i);
      });
  }(i));
}

Bu işlev bir söz verirse, o zincirleme etkisini elde edersiniz.

Sözler hakkında daha fazla bilgi MDN.


İle basitleştirilebilir let (ve ok fonksiyonları):

var p = Promise.resolve();
for (let i=1; i<=10; i++) {
    p = p.then(() => promiseReturner(i));
}

Veya .bind (ES5 olan):

var p = Promise.resolve();
for (var i=1; i<=10; i++) {
    p = p.then(promiseReturner.bind(null, i));
}

22
2018-02-23 20:58



Belki daha açık: "bir işlevi geçmek zorundasın bir söz vermek"? - Jos de Jong
Daha sonra açıkladığınızı boşver - Jos de Jong
Daha önce bir işlevde sarmayı denedim buraya bakınAma sadece son sözü yerine getiriyor gibiydi. Neden bunu kendi kendine çalan bir işleve bloke etmek onu düzeltiyor gibi görünüyor? - Ben Davis
@BenDavis: Döngüler içinde JavaScript kapatma - basit pratik örnek. tl; dr: Javascript yalnızca kapsamı değil, kapsamı değil, her fonksiyon aynıdır i. Bu ile sabit let Btw. - Felix Kling
Ah teşekkürler! Kendi kendime kafamı karıştırdım, çünkü sözümün sözünü edindim. Tekrarlayan fonksiyonun kendisi bir işlevdi, ama bu fonksiyonun sonucunu (fonksiyonun kendisinin değil) geçtiğimin farkında değildim. 15 yıldır kodlayan birinin bunu yakalayacağını düşünürsün. Git rakamı. - Ben Davis


Es6 kullanıyorsanız, bunu kullanarak başarabilirsiniz. array.reduce. Oldukça düzgünce düşünüyorum.

const functions = [/* array of functions which return promises */];
const finalPromise = functions.reduce(async (promise, asyncFn) => {
  await promise;
  return asyncFn();
}, Promise.resolve());

2
2017-07-07 15:07





Kullanabilirsiniz async/await es6 jeneratörler ve benzeri bir kütüphane kullanarak ko.

co(function* () {
  while(upto < 10) {
    var result = yield Promise.resolve(true);
  }
  return result;
}).then(function (value) {
  console.log(value);
}, function (err) {
  console.error(err.stack);
});

İşte bunun nasıl çalıştığını biraz ayrıntı: http://davidwalsh.name/async-generators


1
2018-02-23 21:00





İşte aynı sorunu çözmek için kullandığım bir çözüm:

var recursiveFunction = function(values) {
  return new Promise(function(resolve, reject) {
    if (values.length <= 0) {
        return resolve();
    } else {
        return promiseReturner(values[0]).then(function() {
            values.shift();
            return recursiveFunction(values).then(function() {
              resolve();
            });
        });
      }
  });
}

recursiveFunction([1,2]).then(function(r) {
 console.warn('Finished solving promises sequentially');
})

1
2017-12-23 02:51





Kodunuzu üzerinden çalıştırabilirsiniz. nsynjsBu, söz verilen her işlevde yürütmeyi duraklatır ve söz verilinceye kadar bekler:

var promiseReturner = function(i) {
    return new Promise(function(resolve, reject) {
        setTimeout(function(){
            resolve("result is "+i)
        }, 1000);
    });
};

function synchronousCode() {
    for (var i=1; i<=10; i++) {
        var p=promiseReturner(i); // nsynjs will pause here until promise is resolved
        console.log(p.data); // `data` will contain result of the promise
    }
};
	
nsynjs.run(synchronousCode, null, function(){
	console.log("finish");
});
<script src="https://rawgit.com/amaksr/nsynjs/master/nsynjs.js"></script>


-1
2017-07-07 15:41