web-dev-qa-db-fra.com

La façon correcte de lier un objet à l'argument Promise.then ()

J'ai découvert à la dure que l'on ne peut pas simplement passer la fonction d'un objet dans le Bluebird then. Je suppose que then de Bluebird fait de la magie et encapsule la fonction passée dans une fonction anonyme. J'ai donc joint un .bind à la fonction et cela a fonctionné. Est-ce la bonne façon de procéder avec Bluebird? Ou existe-t-il un meilleur moyen?

var Promise = require("bluebird")

var Chair = function(){
  this.color = "red"
  return this
}


Chair.prototype.build = function(wood){
  return this.color + " " + wood
}

var chair = new Chair()

//var x = chair.build("cherry")

Promise.resolve("cherry")
  .then(chair.build.bind(chair)) // color is undefined without bind
  .then(console.log)

Je sais que rien de tout cela n'est asynchrone, veuillez donc montrer l'exemple de synchronisation, mon utilisation est asynchrone.

23
ThomasReggi

J'ai donc attaché un .bind À la fonction et cela a fonctionné. Est-ce la bonne façon de procéder avec Bluebird?

Oui, c'est une façon de conserver le contexte. Vous pouvez également transmettre une fonction anonyme (vous le savez peut-être déjà).

Promise.resolve("cherry")
    .then(function (value) {
        return chair.build(value);
    })
    .then(console.log);

Ou existe-t-il un meilleur moyen?

Vous pouvez réellement utiliser la méthode Promise.bind de bluebird, comme celle-ci

Promise.resolve("cherry")
  .bind(chair)
  .then(chair.build)
  .then(console.log)

Désormais, chaque fois que les gestionnaires Promise (gestionnaires d'exécution ou gestionnaires de rejet) sont appelés, à l'intérieur de la fonction, this fera uniquement référence à l'objet chair.


Remarque 1: Dans ce cas spécifique, console.log Obtient également this comme objet chair, mais cela fonctionne toujours bien, car, dans Node.js, la fonction console.log est définie non seulement sur le prototype mais également sur l'objet lui-même, lié à l'objet console. Le code correspondant est ici .

Remarque 2: Si différents gestionnaires ont besoin de contextes différents, il vaut mieux écrire des fonctions anonymes. Dans ce cas, Promise.bind N'aidera pas beaucoup. Mais si vous choisissez de l'utiliser, vous devez utiliser différents contextes pour chacun des gestionnaires et votre code pourrait ressembler à ceci

var chair1 = new Chair("red")
var chair2 = new Chair("green")

Promise.resolve("cherry")
    .bind(chair1)            // Changing the binding to `chair1`
    .then(chair1.build)
    .tap(console.log)
    .bind(chair2)            // Changing the binding to `chair2`
    .then(chair2.build)
    .tap(console.log);
24
thefourtheye