Promette, passare parametri aggiuntivi per poi concatenare


100

Una promessa, solo per esempio:

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

Dopo aver chiamato, quindi il metodo sulla promessa:

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

La funzione doWork ha questo aspetto:

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

Come posso evitare di restituire una funzione interna in doWork, per ottenere l'accesso ai dati dalla promessa e dai parametri di testo? Ci sono trucchi per evitare la funzione interiore?


1
Perché qualcuno dovrebbe rinunciare intenzionalmente al curry ? Per usare il bindmetodo orribile ? - che è anche estremamente lento.

@ftor non ti capisco, puoi fornire del codice per chiarimenti?
Roland

Risposte:


86

Puoi usare Function.prototype.bindper creare una nuova funzione con un valore passato al suo primo argomento, come questo

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

e puoi passare doWorka

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

Ora, textsarà in realtà 'text'in doWorke datasarà il valore risolto dalla promessa.

Nota: assicurati di allegare un gestore del rifiuto alla catena di promesse.


Programma di lavoro: copia live su REPL di 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);

grazie, questo aiuta, prima provo doWork.call (questo, 'testo'), ma i dati sono stati sostituiti da 'testo'
user3110667

2
callinvoca una funzione sul posto, bindcrea una nuova funzione, tuttavia entrambi accettano un contesto di esecuzione come primo argomento.
sdgluck

103

Forse la risposta più semplice è:

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

Oppure, poiché questo è contrassegnato ecmascript-6, utilizzando le funzioni freccia:

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

Lo trovo molto leggibile e non troppo da scrivere.


5

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

b attenzione con questo, se crei curriedDoWorkuna promessa facendo return new Promise()sulla prima riga di questa funzione, la promessa viene eseguita non appena chiami curriedDoWork()(come fai in..then(curriedDoWork('text'))
Flame

@Flame: risposta breve, per tua comodità puoi racchiudere la promessa in una funzione, se lo desideri.
germain

@yks, avresti potuto indicare questa sintassi che è piuttosto interessante const curriedWork = text => data => console.log (data + text)
germain

1
@germain ah sì ho già visto questo modulo, devo amare la programmazione funzionale. Tuttavia ho riscontrato che le funzioni delle frecce si interrompono in alcuni browser, quindi tendo a evitarlo ora.
yks

@yks, solo Internet Explorer non lo supporta e non lo sarà mai, a causa di Edge, l'ultima build di Internet Explorer è stata il 9 dicembre 2015. Andiamo avanti ~
germain

0

Lodash offre una bella alternativa per questa cosa esatta.

 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
 }

Oppure, se desideri che la tua funzione di successo abbia un solo parametro (i risultati della promessa mantenuta), puoi utilizzarla in questo modo:

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

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

Questo si collegherà text: 'myArgString'al thiscontesto all'interno della funzione.


0

La nuova risposta a questa domanda è usare le funzioni freccia, che legano automaticamente il "questo" ed è molto più leggibile. Google per collegamenti come: https://2ality.com/2016/02/arrow-functions-vs-bind.html

Puoi impostare il testo in questo modo: this.text = 'text' P.then (data => doWork (data)); // questo.testo all'interno di doWork restituirà 'testo'.

Questo è suggerito dal fiocco sopra e quella (o questa!) Dovrebbe essere la risposta accettata ora.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.