How to connect multiple promises?

I'm not quite sure, and maybe I am missing something obvious, but I cannot figure out how to link the two promises.

My callback based code looks something like this:

async.series([
function (cb) {
  // Create the directory if the nodir switch isn't on
  if (!nodir) {
    fs.mkdir('somedirectory', function (err) {
      if (err) {
        log('error while trying to create the directory:\n\t %s', err)
        process.exit(0)
      }
      log('successfully created directory at %s/somedirectory', process.cwd())
      cb(null)
    })
  }
  cb(null)
},
function (cb) {
  // Get the contents of the sample YML
  fs.readFile(path.dirname(__dirname) + '/util/sample_config.yml', function (err, c) {
    var sampleContent = c
    if (err) {
      log('error while reading the sample file:\n\t %s', err)
      process.exit(0)
    }
    log('pulled sample content...')
    // Write the config file
    fs.writeFile('db/config.yml', sampleContent, function (err) {
      if (err) {
        log('error writing config file:\n\t %s', err)
        process.exit(0)
      }
      log('successfully wrote file to %s/db/config.yml', process.cwd())
      cb(null)
    })
  })
}
])

I started trying to reorganize this into a promise-based thread, this is what I still have:

if (!nodir) {
fs.mkdirAsync('somedirectory').then(function () {
  log('successfully created directory at %s/somedirectory', process.cwd())
}).then(function () {
  // how can I put fs.readFileAsync here? where does it fit?
}).catch(function (err) {
  log('error while trying to create the directory:\n\t %s', err)
  process.exit(0)
})
}

(I use Bluebird, so I did Promise.promisifyAll(fs)before)

The problem is that I do not know where to put the second "step" of the previous series. Do I put it in thenor in its function? Do I return it and put it in a separate function?

Any help would be greatly appreciated.

+4
source share
2 answers

Typically, the code with promises is as follows:

operation.then(function(result) {
  return nextOperation();
}).then(function(nextResult) {
  return finalOperation();
}).then(function(finalResult) {
})

, :

Promise.resolve().then(function() {
  if (nodir) {
    return fs.mkdir('somedirectory').catch(function(err) {
      log('error while trying to create the directory:\n\t %s', err);
      process.exit(0);
    });
  }
}).then(function() {
  return fs.readFile(path.dirname(__dirname) + '/util/sample_config.yml').catch(function(err) {
    log('error while reading the sample file:\n\t %s', err);
    process.exit(0);
  })
}).then(function(sampleContent) {
  log('pulled sample content...');

  return fs.writeFile('db/config.yml', sampleContent).catch(function(err) {
    log('error writing config file:\n\t %s', err)
    process.exit(0)
  })
}).then(function() {
  log('successfully wrote file to %s/db/config.yml', process.cwd())
})

, .

Promise.resolve() - , , .

+3

Bluebird, , IMO:

var fs = Promise.promisifyAll(fs); // tell bluebird to work with FS
Promise.try(function(){ 
  if(nodir) return fs.mkdirAsync('somedirectory').
                      catch(catchErr("Could not create dir"));
}).then(function(){
    return fs.readFileAsync(path.dirname(__dirname) + '/util/sample_config.yml').
             catch(catchErr("error while reading the sample file"));
}).then(function(data){
  log('pulled sample content...');
  return fs.writeFile('db/config.yml', data).
            catch(catchErr("error writing config file"));
}).then(function(){
  log('successfully wrote file to %s/db/config.yml', process.cwd())
}, function(err){
    // centralized error handling, to remove the redundancy
    log(err.message);
    log(err.internal);
    log(err.stack); // this is important! 
});


function catchErr(msg){ // helper to rethrow with a specific message
    return function(e){
        var err = new Error(msg);
        err.internal = e; // wrap the error;
        throw e;
    };
}

, , , , API, - :

Promise.try(function(){
    if(nodir) return fs.mkdirAsync("somedirectory");
}).then(function(){
    fs.readFileAync(path.dirname(__dirname) + '/util/sample_config.yml');
}).then(function(data){
    log('pulled sample content...');
    return fs.writeFile('db/config.yml', data);
}).then(function(){
  log('successfully wrote file to %s/db/config.yml', process.cwd())
}).catch(function(err){
    log(err);
    process.exit(1);
});

Promises - , . , io.js node, :

Promise.coroutine(function*(){ // generators ftw
  if(nodir) yield fs.mkdirAsync("somedirectory");
  var data = yield fs.readFileAsync(path.dirname(__dirname) + '/util/sample_config.yml');
  log("pulled sample content");
  yield fs.writeFileAsync("db/config.yml", data);
  log('successfully wrote file to %s/db/config.yml', process.cwd());
})();

process.on("unhandledRejection", function(p, r){
    throw r; // quit process on promise failing
});
+2

Source: https://habr.com/ru/post/1589500/


All Articles