web-dev-qa-db-fra.com

flux if-else en promesse (merle bleu)

Ceci est une version courte de mon code.

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

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

Les deux conditions appellent functionA. Existe-t-il un moyen d'éviter une autre condition? Je peux faire fs.writeFileSync mais je recherche une solution non bloquante.

39
vinayr

Je pense que tu cherches

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

ce qui est court pour

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();
});
61
Bergi

Bien que d'autres suggestions fonctionnent, personnellement, je préfère les suivantes.

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

Il a l'inconvénient de toujours créer cette promesse supplémentaire (OMI plutôt mineure) mais semble beaucoup plus propre à mes yeux. Vous pouvez également ajouter facilement d'autres conditions/logiques à l'intérieur de l'IIFE.

MODIFIER

Après avoir implémenté des choses comme ça depuis longtemps maintenant, j'ai définitivement changé pour quelque chose de légèrement plus clair. La promesse initiale est créée malgré tout, il est donc beaucoup plus clair de simplement faire:

/* 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
if (someCondition) return somePromise;

à l'intérieur de la première fonction .then ().

9
Goblinlord

Vous pouvez toujours utiliser Promise.all() avec la fonction conditionnelle

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

Ou, si vous voulez que functionA soit appelé uniquement après que le fichier a peut-être été écrit, vous pouvez séparer:

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