web-dev-qa-db-fra.com

Enchaîner les promesses dans Coffeescript

Existe-t-il un moyen de chaîner Promises ensemble dans Coffeescript. Par exemple, considérez le code javascript suivant,

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

Chacun de then's est facultatif, et le then final doit être retourné par la fonction. Actuellement, j'écris ceci en coffeescript comme,

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

Y a-t-il une meilleure manière de faire cela? Merci.

29
Darshan Sawardekar

Ezéchiel montre la bonne voie, mais il n'a pas besoin des parenthèses autour des fonctions. Faites juste:

$.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

Je pense que c'est étonnamment propre. La seule chose qui est relativement compliquée, c'est quand vous devez ajouter des gestionnaires onRejected et onFulfilled en même temps.

Remarque: La dernière fois que j'ai vérifié, cela ne fonctionnait pas dans CoffeeScript Redux, mais c'était il y a quelques mois.

Remarque 2: vous avez besoin d'au moins une ligne de code réel (c'est-à-dire pas seulement un commentaire) dans chaque corps de fonction pour que cela fonctionne. Généralement, vous le ferez, donc ce n'est pas un gros problème.

43
Myrne Stol

C'est ma façon préférée d'écrire des promesses, avec un peu d'indentation supplémentaire

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'

Qui se compile pour:

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');
});

Il y a des cas où cela fonctionne très bien aussi:

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)

Testé sur Coffee-Script v1.6.3

13
James Kyle

C'est probablement le mieux que vous ferez:

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

Notez les parenthèses entourant les arguments then(). Rien de bouleversant mais j'espère que cela aide.

4
Ezekiel Victor