2016-04-14 6 views
2

Wie man Funktionen mit Verzögerungen kettet. Ich habe folgendes versucht:ES6 verspricht: wie Funktionen mit Argumenten verkettet werden

Promise.resolve() 
.then(setKeyframe('keyframe-0')) 
.then(delay(3000)) 
.then(setKeyframe('keyframe-1')) 
.then(delay(3000)) 
.then(setKeyframe('keyframe-2')) 
; 

function delay(ms) { 
    return new Promise((resolve, reject) => { 
    setTimeout(resolve, ms); 
    }); 
} 

function setKeyframe (name) { 
    var element = document.getElementsByClassName('animation-container')[0]; 
    element.className = 'animation-container ' + name; 
} 

Alle Funktionen scheinen sofort nacheinander aufgerufen zu werden. Die Verzögerungsfunktion verzögert die Kette nicht. Was vermisse ich?

+4

Sie haben einen Rückruf zu übergeben, die ein Versprechen in 'then' zurückkehrt, kein Versprechen selbst. – Bergi

+0

Sie beginnen alle Aktionen auf einmal –

Antwort

3

.then() übernimmt eine Funktion, die kein Versprechen zurückkehren kann oder

Sie sind ein Versprechen direkt aber vorbei

// Yes 
Promise.resolve().then(() => { return new Promise(); }); 

// No 
Promise.resolve().then(new Promise()); 
+0

Entschuldigung. Ich verstehe deine Antwort nicht. Sprechen Sie über die Funktion delay()? Was ist der Unterschied zwischen "eine Funktion weitergeben, die ein Versprechen zurückgibt" und "ein Versprechen direkt weitergibt"? – Sven

+0

@Sven, nein, beide. Siehe meine Antwort. – Qwertiy

+0

Es ist der Unterschied zwischen ... Promise.resolve(). Dann (new Promise()); Promise.resolve(). Then (() => {return new Promise();}); –

2

Es ist, weil Sie alle Funktionen aufrufen wurden, anstatt sie als Handler bereitstellt.

Promise.resolve('keyframe-0') 
 
.then(setKeyframe) 
 
.then(delay(3000, 'keyframe-1')) 
 
.then(setKeyframe) 
 
.then(delay(3000, 'keyframe-2')) 
 
.then(setKeyframe) 
 
; 
 

 
function delay(ms, value) { 
 
    return function (val) { 
 
    return new Promise((resolve, reject) => { 
 
     setTimeout(resolve, ms, value !== undefined ? value : val); 
 
    }); 
 
    }; 
 
} 
 

 
function setKeyframe(name) { 
 
    var element = document.body; 
 
    element.className = 'animation-container ' + name; 
 
}
html, body { 
 
    height: 100%; 
 
    margin: 0; 
 
    padding: 0; 
 
} 
 

 
.keyframe-0 { background: red; } 
 
.keyframe-1 { background: green; } 
 
.keyframe-2 { background: blue; }

+0

Besser benennen Sie es in 'makeDelayer' oder so, um klar zu machen, dass es nicht sofort eine Verzögerung erzeugt. – Bergi

5

Ihr Fehler könnte einfacher sein, ohne Argumente mit einer Funktion zu erkennen:

Der richtige Weg:

Promise.resolve().then(setFirstKeyframe) 

über die Funktion setFirstKeyframe ist ein Argument .then, für das Versprechen, später anzurufen.

Der falsche Weg:

Promise.resolve().then(setFirstKeyframe()) 

Hier wird setFirstKeyframe rief sofort, und das Ergebnis (ein Versprechen) an then geben (die ignoriert wird als then eine Funktion erwartet) (!).

Für Funktionen mit Argumenten verwenden eine anonyme Funktion:

Promise.resolve().then(function() { 
    return setFirstKeyframe('keyframe-0'); 
}) 

Hier es6 arrow functions Rock:

Promise.resolve().then(() => setFirstKeyframe('keyframe-0')) 
Verwandte Themen