2015-10-02 3 views
65

Versprechen Kette, nur zum BeispielPromises, zusätzliche Parameter übergeben, um dann

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

Nachdem wir dann Methode auf Versprechen nennen:

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

doWork Funktion wie folgt aussieht:

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.

+1

Warum sollte jemand absichtlich ** currying ** verzichten? Um die abscheuliche 'bind' Methode zu benutzen? - Das ist auch sehr langsam. – ftor

+0

@ftor Ich verstehe Sie nicht, können Sie bitte einen Code zur Klärung zur Verfügung stellen? – Roland

Antwort

59

Sie können Function.prototype.bind verwenden, um eine neue Funktion mit einem Wert zu seinem ersten Argument übergeben zu schaffen, wie diese

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

und Sie können doWork ändern,

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

Nun wird text sein tatsächlich 'text' in doWork und data wird der Wert von der Promise gelöst werden.

Hinweis: Stellen Sie sicher, dass Sie einen Ablehnungshandler an Ihre Versprechungskette anfügen.


Arbeitsprogramm:Live copy on Babel's 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); 
+0

danke, das hilft, früher versuche ich doWork.call (this, 'text'), aber die Daten wurden durch 'text' ersetzt – user3110667

+1

'call' ruft eine Funktion vor Ort auf,' bind' erstellt eine neue Funktion, akzeptiert jedoch beide ein Ausführungskontext als erstes Argument. – sdgluck

63

Vielleicht ist die einfachste Antwort lautet:

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

Oder, da diese ecmascript-6 markiert ist, Pfeil Funktionen:

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

Ich finde dies am besten lesbar, und nicht zu viel zu schreiben.

+3

Danke, Letzteres ist einfach schön im Vergleich zu dem, was ich dachte, ich müsste tun. – JollyJoker

0

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 
} 

Oder, wenn Sie Ihren Erfolg Funktion möchten nur ein Parameter (die erfüllt Versprechen Ergebnisse) haben, können Sie es auf diese Weise nutzen:

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

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

Diese text: 'myArgString' an die this anbringt Kontext innerhalb der Funktion.

1

Curry verwenden.

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