javascript - Kan løfter ha flere argumenter til onFulfilled?


Jeg følger spesifikasjonen her, og jeg er ikke sikker på om den tillater at onFulfilled kalles med flere argumenter. For eksempel:

promise = new Promise(function(onFulfilled, onRejected){
    onFulfilled('arg1', 'arg2');
})

slik at koden min:

promise.then(function(arg1, arg2){
    // ....
});

ville motta både arg1 og arg2?

Jeg bryr meg ikke om hvordan en spesifikk implementering av promises gjør det, jeg ønsker å følge W3C-spesifikasjonen for promises nøye.

Svar #1

Jeg følger spesifikasjonen her, og jeg er ikke sikker på om den tillater at onFulfilled blir kalt med flere argumenter.

Nei, bare den første parameteren vil bli behandlet som oppløsningsverdi i løftkonstruktøren. Du kan løse med en sammensatt verdi som et objekt eller en array.

Jeg bryr meg ikke om hvordan en spesifikk implementering av promises gjør det, jeg ønsker å følge W3C-spesifikasjonen for promises nøye.

Der tror jeg du tar feil. Spesifikasjonen er utformet for å være minimal og er bygget for å kunne samhandle mellom løfte-biblioteker. Ideen er å ha et delsett som for eksempel DOM-futures kan bruke pålitelig, og som biblioteker kan konsumere. Løfteimplementasjoner gjør det du ber om med .spread allerede nå. For eksempel:

Promise.try(function(){
    return ["Hello","World","!"];
}).spread(function(a,b,c){
    console.log(a,b+c); // "Hello World!";
});

Med Bluebird. Én løsning hvis du vil ha denne funksjonaliteten er å polyfille den.

if (!Promise.prototype.spread) {
    Promise.prototype.spread = function (fn) {
        return this.then(function (args) {
            return Promise.all(args); // wait for all
        }).then(function(args){
         //this is always undefined in A+ complaint, but just in case
            return fn.apply(this, args); 
        });
    };
}

Dette lar deg gjøre:

Promise.resolve(null).then(function(){
    return ["Hello","World","!"]; 
}).spread(function(a,b,c){
    console.log(a,b+c);    
});

Med native-løfter på plass kan du enkelt fjase. Eller bruk spread, som nå (2018) er vanlig i nettlesere:

Promise.resolve(["Hello","World","!"]).then(([a,b,c]) => {
  console.log(a,b+c);    
});

Eller med await:

let [a, b, c] = await Promise.resolve(['hello', 'world', '!']);

Svar #2

Du kan bruke E6-destructuring:

Objektdestrukturering:

promise = new Promise(function(onFulfilled, onRejected){
    onFulfilled({arg1: value1, arg2: value2});
})

promise.then(({arg1, arg2}) => {
    // ....
});

Array-destrukturering:

promise = new Promise(function(onFulfilled, onRejected){
    onFulfilled([value1, value2]);
})

promise.then(([arg1, arg2]) => {
    // ....
});

Svar #3

Oppfyllelsesverdien til et løfte tilsvarer returverdien til en funksjon, og avvisningsgrunnen til et løfte tilsvarer det kastede unntaket til en funksjon. Funksjoner kan ikke returnere flere verdier, så løfter må ikke ha mer enn én oppfyllelsesverdi.

Relaterte artikler