Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Promises to call function inside another function with Bluebird promises library

I have 3 Node Js functions. What I'm trying to do here is, I want to call normalizeFilePath and get the normalized path, after that check whether a file exist or not with that normalizedFilePath and after all these, create a file if the file doesn't already exist. This is the first day of using promises (Bluebird) and I'm new to Node JS and Java Script. Below code structure is getting complex. Of course this is not a good idea at all.

var createProjectFolder = function (projectName) {

};


var checkFileExistance = function (filePath) {
  return new promise(function (resolve, reject) {
    normalizeFilePath(filePath).then(function (normalizedFilePath) {
      return fs.existSync(normalizedFilePath);
    });
  })

};

var normalizeFilePath = function (filePath) {
  return new promise(function (resolve, reject) {
    resolve(path.normalize(filePath));
  });
};

How can i manage promises to implement that concept?

like image 709
s1n7ax Avatar asked Apr 22 '16 19:04

s1n7ax


People also ask

How do you call a function inside a promise?

Here we need to first declare a Promise by using the Promise syntax, and we will be using the then() method for its execution and then inside that then() method we will create another promise by using the same Promise syntax as illustrated above, and then we will call our result of first inside that new Promise.

Can promises be nested?

Nested Promise: Promises give you return statements and error throwing, which you lose with continuation-passing style. A nested promise is when you call child promise inside . then of parent promise and this go-on.

Can a promise handle synchronous?

A promise is used to handle the asynchronous result of an operation. JavaScript is designed to not wait for an asynchronous block of code to completely execute before other synchronous parts of the code can run. With Promises, we can defer the execution of a code block until an async request is completed.

Does promise all run promises in parallel?

As you can see, Promise. all executes code concurrently, but what is parallel execution? JavaScript is single-threaded and can only perform a single chunk of work at a time, so parallel execution is not possible with JavaScript, except for some circumstances such as web workers.


1 Answers

Let's improve your code in two simple steps.

Promises are meant for async functions

As long as path.normalize is synchronous, it should not be wrapped in promise.

So it can be as simple as that.

var normalizeFilePath = function (filePath) {
  return path.normalize(filePath);
};

But for now lets pretend that path.normalize is async, so we can use your version.

var normalizeFilePath = function (filePath) {
  return new Promise(function (resolve, reject) {
    resolve( path.normalize(filePath) );
  });
};

Promisify all the things

Sync is bad. Sync blocks event loop. So, instead of fs.existsSync we will use fs.exists.

var checkFileExistance = function (filePath) {
  return new Promise(function (resolve, reject) {
    fs.exists(filePath, function (exists) {
      resolve(exists);
    });
  });
};

As You can see, we are wrapping async function that accepts a callback with a promise. It's quite a common concept to "promisify" a function, so we could use a library for that. Or even use fs-promise, that is -- you guess it -- fs with promises.

Chaining promises

Now, what we want is making three actions one after another:

  1. Normalize file path
  2. Check if file already exists
  3. If not, create a directory

Keeping that in mind, our main function can look like this.

var createProjectFolder = function (projectName) {
    normalizeFilePath(projectName)
      .then(checkFileExistance)
      .then(function (exists) {
        if (!exists) {
          // create folder
        }
      })
      .catch(function (error) {
        // if there are any errors in promise chain
        // we can catch them in one place, yay!
      });
};

Don't forget to add the catch call so you would not miss any errors.

like image 145
Роман Парадеев Avatar answered Oct 13 '22 11:10

Роман Парадеев