Frage Verheißt, übergebe zusätzliche Parameter um dann zu verketten


Versprechen, nur zum Beispiel

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

Nach dem Aufruf rufen wir dann die Methode auf Versprechen:

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

Die doWork-Funktion sieht folgendermaßen aus:

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

Wie kann ich innere Funktion in DoWork vermeiden, um Zugriff auf Daten von Versprechen und Textparameter zu erhalten? wenn es irgendwelche Tricks gibt? Vielen Dank.


75
2017-10-02 17:15


Ursprung


Antworten:


Sie können verwenden Function.prototype.bind um eine neue Funktion mit einem Wert zu erzeugen, der an das erste Argument übergeben wird, wie dies hier der Fall ist

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

und du kannst dich ändern doWork zu,

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

Jetzt, text wird eigentlich sein 'text' im doWork und data wird der durch das Versprechen gelöste Wert sein.

Hinweis: Stellen Sie sicher, dass Sie einen Ablehnungshandler an Ihre Versprechungskette anhängen.


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

68
2017-10-02 17:23



Vielleicht ist die einfachste Antwort:

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

Oder, da dies markiert ist ecmascript-6, mit Pfeilfunktionen:

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

Ich finde das am besten lesbar und nicht zu viel zum schreiben.


75
2017-10-05 00:15



Verwende Curry.

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
2017-10-22 10:53



Lodash bietet eine schöne Alternative für genau diese Sache.

 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 hat (die erfüllten Versprechensergebnisse), 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
}

Dies wird anhängen text: 'myArgString' zum this Kontext innerhalb der Funktion.


1
2018-05-19 19:47