2014-10-28 9 views
36

Questa è una versione breve del mio codice.if-else flow in promise (bluebird)

var Promise = require('bluebird'); 
var fs = Promise.promisifyAll(require("fs")); 

if (conditionA) { 
    fs.writeFileAsync(file, jsonData).then(function() { 
    return functionA(); 
    }); 
} else { 
    functionA(); 
} 

Entrambe le condizioni chiamano functionA. C'è modo di evitare altre condizioni? Posso fare fs.writeFileSync ma sto cercando una soluzione non bloccante.

+0

Promise è progettato per il controllo delle attività asincrone. Perché usare la sincronizzazione sync? Puoi semplicemente controllare il valore di ritorno di 'writeFileAsync'. – CodeColorist

risposta

52

Penso che tu sia alla ricerca di

(conditionA 
    ? fs.writeFileAsync(file, jsonData) 
    : Promise.resolve()) 
.then(functionA); 

che è breve per

var waitFor; 
if (conditionA) 
    waitFor = fs.writeFileAsync(file, jsonData); 
else 
    waitFor = Promise.resolve(undefined); // wait for nothing, 
              // create fulfilled promise 
waitFor.then(function() { 
    return functionA(); 
}); 
2

Si può sempre usare Promise.all() con funzione di

var condition = ...; 

var maybeWrite = function(condition, file, jsonData){ 
    return (condition) ? fs.writeFileAsync(file, jsonData) : Promise.resolve(true); 
} 

Promise.all([maybeWrite(condition, file, jsonData),functionA()]) 
.then(function(){ 
    // here 'functionA' was called, 'writeFileAsync' was maybe called 
}) 

condizionato o, se si vuole functionA chiamato solo dopo aver scritto il file, è possibile separare:

maybeWrite(condition, file, jsonData) 
.then(function(){ 
    // here file may have been written, you can call 'functionA' 
    return functionA(); 
}) 
+0

Il mio * unico * problema con questo approccio è la manutenibilità. Ti iscrivi per dover "districare" le cose lungo la linea. Qual è uno dei vantaggi delle catene Promise: la tua logica è sentimento lineare. –

7

Mentre altri suggerimenti qui funzionano, personalmente preferisco quanto segue.

Promise.resolve(function(){ 
    if (condition) return fs.writeFileAsync(file, jsonData); 
}()) 
.then() 

ha lo svantaggio di creare sempre questa promessa aggiuntiva (piuttosto minore IMO), ma sembra molto più pulito al mio occhio. È inoltre possibile aggiungere facilmente altre condizioni/logica all'interno dell'IIFE.

EDIT

Dopo aver implementato le cose come questo per lungo tempo ho decisamente cambiato a qualcosa di un po 'più chiaro. La promessa iniziale viene creato a prescindere quindi è molto più chiaro semplicemente fare:

/* Example setup */ 
 

 
var someCondition = (Math.random()*2)|0; 
 
var value = "Not from a promise"; 
 
var somePromise = new Promise((resolve) => setTimeout(() => resolve('Promise value'), 3000)); 
 

 

 
/* Example */ 
 

 
Promise.resolve() 
 
.then(() => { 
 
    if (someCondition) return value; 
 
    return somePromise; 
 
}) 
 
.then((result) => document.body.innerHTML = result);
Initial state
In realtà, nel tuo caso sarebbe semplicemente

if (someCondition) return somePromise; 

all'interno del primo .then() funzione.