2017-03-03 5 views
4

Ich versuche, eine Reihe von Versprechen in der Reihenfolge auszuführen, nur zum nächsten zu gehen, nachdem das vorherige gelöst ist. Von Bluebird docs:Bluebird mapSeries

Der Iterator wird für ein Element erst nach dem vorherigen Element aufgerufen, und die vom Iterator für dieses Element zurückgegebene Zusage ist erfüllt. http://bluebirdjs.com/docs/api/promise.mapseries.html

var Promise = require('bluebird'); 


function test(time) { 
    return new Promise(function(resolve, reject) { 
     setTimeout(function() { 
      console.log(time); 
      resolve(time); 
     }, time); 
    }); 
} 

Promise.mapSeries([test(2000), test(1000), test(500), test(3000)], function(a) { 
    return a; 
}).then(function(results) { 
    console.log(results); 
}); 

Was ich erwarte, ist, dass die console.log innerhalb der Testfunktion zu zeigen: 2000, 1000, 500, 3000 in dieser Reihenfolge. Ich erwarte, dass, wie die Dokumentation sagt, jedes Element erst nach der vorherigen ausgeführt wird. Stattdessen bekomme ich 500, 1000, 2000, 3000, was zeigt, dass alle Funktionen sofort aufgerufen werden. Außerdem zeigen die Ergebnisse die Ergebnisse in der Reihenfolge, in der sie aufgerufen wurden, obwohl dies an dieser Stelle irrelevant ist.

Darf ich etwas falsch verstehen?

+0

_Creating_ ein Versprechen (was "test" ist) ist eine synchrone Operation. – robertklep

+0

Sicher, ich erwarte immer noch, dass Bluebird etwas magisch macht und darauf wartet, den nächsten Test anzurufen, bis der vorherige fertig ist. Sagt das nicht der Doc? – yBrodsky

+1

Es gibt einen Unterschied zwischen einem Iterator, der Versprechungen für einen Gegenstand zurückgibt, und Gegenständen, die selbst versprechen (was in Ihrem Fall passiert). Sobald Sie 'test' aufrufen, wird das Versprechen, das es zurückgibt," gestartet "(so wird' setTimeout' aufgerufen). Die Antwort zeigt, wie die Erstellung des Versprechens verschoben werden kann, bis Bluebird explizit darum bittet (nur so kann es funktionieren). – robertklep

Antwort

5

Ihre Testanrufe sind vor Promise.mapSeries wird jemals eine Chance zu laufen. Auch mapSeries wird normalerweise auf einer Promise-Instanz ausgeführt. Vielleicht hilft das folgende Beispiel zu verstehen? Beachten Sie, wie Test (Zeit) diese Zeit gibt eine Funktion zurück.

function test(time) { 
    return function(value) { 
     return new Promise(function(resolve, reject) { 
      setTimeout(function() { 
       console.log('time', time); 
       resolve(time); 
      }, time); 
     }); 
    }; 
} 

Promise.resolve([test(2000), test(400), test(1000), test(1), test(5000)]) 
     .mapSeries(function(asyncMethodPassed) { 
    return asyncMethodPassed(); 
}).then(function(results) { 
    console.log('result', results); 
}); 
+0

Gut, vielen Dank. – yBrodsky

+0

Es ist nur eine Art von Problem, das ich hundertmal mit meinem eigenen Code hatte :-) –