web-dev-qa-db-ger.com

Verspricht, zusätzliche Parameter an die Kette übergeben

Ein Versprechen, nur zum Beispiel:

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

Nachdem wir dann die Methode auf das Versprechen rufen:

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

doWork-Funktion sieht so aus:

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

Wie kann ich vermeiden, eine innere Funktion in DoWork zurückzugeben, um aus den Versprechungs- und Textparametern auf Daten zuzugreifen? Gibt es irgendwelche Tricks, um die innere Funktion zu vermeiden?

81
user3110667

Sie können Function.prototype.bind verwenden, um eine neue Funktion zu erstellen, deren Wert an das erste Argument übergeben wird

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

und Sie können doWork in ändern,

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

Nun wird text tatsächlich 'text' in doWork und data der Wert, der durch die Versprechung aufgelöst wird.

Hinweis: Bitte stellen Sie sicher, dass Sie einen Ablehnungs-Handler an Ihre Versprechenkette anschließen.


Arbeitsprogramm:Live-Kopie auf Babels REPL

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

Die einfachste Antwort lautet vielleicht:

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

Da dies mit ecmascript-6 gekennzeichnet ist, verwenden Sie die Pfeilfunktionen:

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

Ich finde das am lesbarsten und nicht zu viel zu schreiben.

88
jib

Verwenden Sie 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 bietet für diese Sache eine schöne Alternative.

 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
 }

Wenn Sie möchten, dass Ihre Erfolgsfunktion nur einen Parameter (die erfüllten Versprechenergebnisse) hat, können Sie sie folgendermaßen verwenden:

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

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

Dadurch wird text: 'myArgString' an den this-Kontext in der Funktion angehängt.

0
JellyRaptor