web-dev-qa-db-fra.com

Promesses, transmettre des paramètres supplémentaires à la chaîne

Une promesse, par exemple:

var P = new Promise(function (resolve, reject) {
  var a = 5;
  if (a) {
    setTimeout(function(){
      resolve(a);
    }, 3000);
  } else {
    reject(a);
  }
});

Après avoir appelé, puis la méthode sur la promesse:

P.then(doWork('text'));

la fonction doWork ressemble à ceci:

function doWork(data) {
  return function(text) {
    // sample function to console log
    consoleToLog(data);
    consoleToLog(b);
  }
}

Comment puis-je éviter de renvoyer une fonction interne dans doWork, pour avoir accès aux données des paramètres de promesse et de texte? Existe-t-il des astuces pour éviter la fonction interne?

81
user3110667

Vous pouvez utiliser Function.prototype.bind pour créer une nouvelle fonction avec une valeur passée au premier argument, comme ceci

P.then(doWork.bind(null, 'text'))

et vous pouvez changer doWork en,

function doWork(text, data) {
  consoleToLog(data);
}

Maintenant, text sera réellement 'text' dans doWork et data sera la valeur résolue par la promesse.

Remarque: Assurez-vous de joindre un gestionnaire de rejet à votre chaîne de promesse.


Programme de travail:Copie en direct sur le REPL de Babel

function doWork(text, data) {
  console.log(text + data + text);
}

new Promise(function (resolve, reject) {
    var a = 5;
    if (a) {
      setTimeout(function () {
        resolve(a);
      }, 3000);
    } else {
      reject(a);
    }
  })
  .then(doWork.bind(null, 'text'))
  .catch(console.error);
73
thefourtheye

La réponse la plus simple est peut-être:

P.then(function(data) { return doWork('text', data); });

Ou, puisque ceci est étiqueté ecmascript-6, en utilisant les fonctions de flèche:

P.then(data => doWork('text', data));

Je trouve cela très lisible et pas trop à écrire.

88
jib

Utilisez currying.

var P = new Promise(function (resolve, reject) {
    var a = 5;
    if (a) {
        setTimeout(function(){
            resolve(a);
        }, 3000);
    } else {
        reject(a);
    }
});

var curriedDoWork = function(text) {
    return function(data) {
        console.log(data + text);
    }
};

P.then(curriedDoWork('text'))
.catch(
    //some error handling
);
3
yks

Lodash offre une alternative intéressante pour cette chose.

 P.then(_.bind(doWork, 'myArgString', _));

 //Say the promise was fulfilled with the string 'promiseResults'

 function doWork(text, data) {
     console.log(text + " foo " + data);
     //myArgString foo promiseResults
 }

Ou, si vous souhaitez que votre fonction de réussite ne comporte qu'un seul paramètre (les résultats de la promesse remplie), vous pouvez l'utiliser de la manière suivante:

P.then(_.bind(doWork, {text: 'myArgString'}));

function doWork(data) {
    console.log(data + " foo " + this.text);
    //promiseResults foo myArgString
}

Ceci va attacher text: 'myArgString' au contexte this dans la fonction.

0
JellyRaptor