2013-07-07 20 views
25

Gibt es eine Möglichkeit, Promises zusammen in Coffeescript zu verketten. Betrachten wir zum Beispiel den folgenden JavaScript-Code,Verkettung Versprechen in Coffeescript

return $.getJSON('/api/post.json') 
    .then(function(response) { 
    // do something 
    }) 
    .then(function(response) { 
    // do something 
    }) 
    .then(null, function(err) { 
    // do something 
    }); 

Jede der then's optional ist, und die endgültige then muss von der Funktion zurückgegeben werden. Derzeit ich dies als in Coffeescript schreibe,

promise = $.getJSON('/api/post.json') 
promise = promise.then (response) -> 
    // do something 

promise = promise.then (response) -> 
    // do something 

promise = promise.then null, (err) -> 
    // do something 

return promise 

Gibt es einen besseren Weg, dies zu tun? Vielen Dank.

+0

Sie könnten auch IcedCoffeeScript ansehen. Es funktioniert ein bisschen anders, aber es funktioniert ganz gut. –

Antwort

40

Ezekiel zeigt den richtigen Weg, aber es braucht nicht die Klammern um die Funktionen. Just do:

$.getJSON '/api/post.json' # As of CoffeeScript 1.7, you don't need the parentheses here either. 
.then (response) -> 
    # do something 
    response # if you would not return anything, promise would be fulfilled with undefined 
.then (response) -> 
    # do something 
    undefined # necessary to prevent empty function body 
.then null, (err) -> 
    # handle error 

Ich denke, es ist überraschend sauber. Die eine Sache, die relativ unordentlich ist, ist, wenn Sie OnRejected und OnFulfilled Handler gleichzeitig hinzufügen müssen.

Hinweis: Das letzte Mal, als ich überprüft habe, funktionierte das nicht in CoffeeScript Redux, aber das war vor ein paar Monaten.

Hinweis 2: Sie benötigen mindestens eine Zeile tatsächlichen Codes (d. H. Nicht nur einen Kommentar) in jedem Funktionskörper, damit dies funktioniert. Normalerweise wirst du es tun, also ist es kein großes Problem.

+0

Danke. Dies funktioniert im Coffeescript-Compiler. –

+0

Downvoted, da dies in CoffeeScript 1.4.0 oder 1.6.3 (neueste Version) nicht kompiliert wird. Die Klammern in meiner Antwort sind erforderlich. –

+4

@EzekielVictor: Danke, wachsam zu sein. Ich habe mich nur darum gekümmert, und das Problem scheint zu sein, dass dem zweiten Teil der Kette ein Funktionskörper fehlte. Der eingerückte Kommentar war anscheinend nicht genug. Ich habe am Ende ein explizites "undefined" hinzugefügt, damit es kompiliert wird. Ich bin nie auf dieses Problem gestoßen, weil ich an diesen Stellen nie nicht leere Funktionskörper hatte. –

4

Dies ist wahrscheinlich das Beste, was Sie tun werden:

$.getJSON('/api/post.json') 
    .then((response) -> 
     # do something 
    ).then((response) -> 
     # do something 
    ).then null, (err) -> 
     # do something 

Beachten Sie die die then() Argumente umgebenden Klammern. Nichts ist erschütternd, aber hoffentlich hilft das.

+0

Danke. Die Klammer zu verlieren, wie @Meryn Stol suggeriert, macht es ein bisschen besser. –

+3

Die Klammern verlieren? Ich nehme an, du meinst sie zu verlieren. Der Gedanke, Klammern an die Welt zu verlieren, ist in der Tat beängstigend. –

12

Dies ist mein persönlicher Favorit Weg Versprechen zu schreiben, mit einer wenig zusätzlichen Vertiefung

doSomething =() -> new RSVP.Promise (resolve, reject) -> 
    if 1 is 1 
    resolve 'Success' 
    else 
    reject 'Error' 

doSomething() 
.then (res) -> 
     console.log 'Step 1 Success Handler' 

    , (err) -> 
     console.log 'Step 1 Error Handler' 

.then (res) -> 
     console.log 'Step 2 Success Handler' 

.then (res) -> 
     console.log 'Step 3 Success Handler' 

    , (err) -> 
     console.log 'Step 3 Error Handler' 

die zu kompiliert:

var doSomething; 

doSomething = function() { 
    return new RSVP.Promise(function(resolve, reject) { 
    if (1 === 1) { 
     return resolve('Success'); 
    } else { 
     return reject('Error'); 
    } 
    }); 
}; 

doSomething().then(function(res) { 
    return console.log('Step 1 Success Handler'); 
}, function(err) { 
    return console.log('Step 1 Error Handler'); 
}).then(function(res) { 
    return console.log('Step 2 Success Handler'); 
}).then(function(res) { 
    return console.log('Step 3 Success Handler'); 
}, function(err) { 
    return console.log('Step 3 Error Handler'); 
}); 

Es gibt einige Fälle, in denen dies auch wirklich gut funktioniert:

step1Success = (res) -> console.log 'Step 1 Success Handler' 
step1Error = (err) -> console.log 'Step 1 Error Handler' 

step2Success = (res) -> console.log 'Step 2 Success Handler' 

step3Success = (res) -> console.log 'Step 3 Success Handler' 
step3Error = (err) -> console.log 'Step 3 Error Handler' 

doSomething() 
    .then(step1Success, step1Error) 
    .then(step2Success) 
    .then(step3Success, step3Error) 

Getestet auf Kaffee-Skript v1.6.3

+0

Das funktioniert gut, und das einzige, was mich für ein bisschen aufhängte, ist sicherzustellen, dass Sie keine Leerzeichen im Code haben. Das ist wahrscheinlich für diejenigen, die neu in coffeescript sind, aber ich konnte Code wie den oben genannten nicht kompilieren, bis ich merkte, dass ich ein einziges Leerzeichen in den Tabs hatte. –