2016-04-25 31 views
5

vedo spesso in altri documenti popoli qualcosa di simile:JavaScript - Restituire la promessa E/O richiamare la chiamata?

callback è facoltativa, se omesso restituisce una promessa.

Questo è quello che ho:

export function doSomeAsync(options, callback) { 

    const useCallback = (callback && typeof callback == 'function'); 

    const promise = new Promise((resolve, reject) => { 

     // --- do async stuff here --- 
     const check = (options.num === 1) ? true : false; 
     setTimeout(() => { 
      if (check) { 
       finish(true, "Number is 1"); 
      } else { 
       finish(false, new Error("Number is not 1")); 
      } 
     }, 1000); 
     // --------------------------- 

     function finish(ok, rtn) { 
      if (useCallback) { 
       if (ok) { 
        callback(null, rtn); 
       } else { 
        callback(rtn, null); 
       } 
      } else { 
       if (ok) { 
        resolve(rtn); 
       } else { 
        reject(rtn); 
       } 
      } 
     } 

    }); 

    return (useCallback) ? false : promise; 
} 

La funzione finish() solo evita un sacco di if... dichiarazioni sparsi.

Sto creando un oggetto promessa, sia che lo utilizzi o no.

test come questo:

doSomeAsync({ num: 1 }).then((result) => { 
    console.log('p result', result); 
}).catch((err) => { 
    console.log('p err', err); 
}); 

doSomeAsync({ num: 1 }, (err, result) => { 
    if (err) { 
     console.log('cb err', err); 
    } else { 
     console.log('cb result', result); 
    } 
}); 

Questo funziona, ma mi chiedo se questo è il modo migliore, o se altri hanno un'un'attuazione migliore e più succinta ..?

+0

Potrebbe essere più appropriato per http://codereview.stackexchange.com/ – Andy

+1

Quale libreria di promessa stai usando? Bluebird ha anche [una funzione dedicata] (http://bluebirdjs.com/docs/api/ascallback.html) per questo. – Bergi

+0

Sto utilizzando Node v4.2.2, con Babel per ES6 ('babel-preset-es2015 6.6.0'), ma non ho installato lo specifico babel ployfill per le promesse. Quindi il Node nativo promette che credo. –

risposta

10

Questo potrebbe essere semplificata se semplicemente sempre usato la promessa, che si sta sempre creando in ogni caso:

export function doSomeAsync(options, callback) { 
    const promise = new Promise((resolve, reject) => { 
     const check = (options.num === 1) ? true : false; 
     setTimeout(() => { 
      if (check) { 
       resolve("Number is 1"); 
      } else { 
       reject(new Error("Number is not 1")); 
      } 
     }, 1000); 
    }); 

    if (callback && typeof callback == 'function') { 
     promise.then(callback.bind(null, null), callback); 
    } 

    return promise; 
} 

vostra funzione è sempre promettere-based, anche nel fatto che essa restituisce sempre una promessa. Il chiamante è semplicemente libero di ignorarlo. L'argomento del callback è semplicemente una "interfaccia fallback legacy" (o "interfaccia alternativa" se si preferisce) per usare quella promessa.

+2

Sì, questo è esattamente l'approccio che stavo pensando. Restituire 'false' sembra un po 'uno spreco - anche (essendo uno sviluppatore .NET e JS) sembra strano restituire due tipi diversi da tale funzione. –

+0

Grazie all'inganno ... Ho aggiornato la mia domanda con le chiamate di prova. Dopo l'aggiornamento per utilizzare il codice ottengo: 'p risultato Numero è 1' e' cb err numero è 1'. Il callback ora ha solo un parametro? –

+0

@Stephen Nel mio esempio precedente, il modo in cui i callback 'promise.then' sono associati,' callback' riceverà un argomento in caso di successo e due argomenti ('false' ed errore) in caso di errore. Il callback dovrebbe avere una firma di 'function (result, err)'. Progetta l'interfaccia come preferisci. – deceze

Problemi correlati