0

I'm trying to understand ES6 promises, and for a second there, I thought I had it, but I guess not.

So I want to create / read a bunch of files and only after this operation has completed, move on to do the next operation. To me, this lends itself nicely to Promises, but I'm getting confused as to why my second operation is returning before my first operation has completed.

I've created a function ensureFileExists which returns a promise, and I pass this as a callback into fileNames.map. This logs an array of true to the console, which is what I'd expect. But my confusion is, I thought that my seconded then would only get called after my first then has completed.

If anyone could elaborate on why my second then is returning before my first then, I'd be grateful.

getFileNames(ensureFileExists) {
  for(let i = 0; i < this.fileCount; i++) {
    this.fileNames.push(this.generateRandomfileNames());
  };
  Promise.all(this.fileNames.map((file) => ensureFileExists(file)))
         .then(values => console.log(values))
         .then(console.log(1)) // Why is this logged before values???
         .catch(err => console.log(err))
};

ensureFileExists(file) {
  return new Promise((resolve, reject) => {
    let filePath = path.join(this.src, file);

    fsExtra.ensureFile(filePath, (err) => {
      if (err === 'undefined') {
        reject(new Error('Error creating file'));
      } else {
        resolve(true);
      }
    });
  })
};
Alexander O'Mara
  • 58,688
  • 18
  • 163
  • 171
hloughrey
  • 958
  • 3
  • 11
  • 22

2 Answers2

3

This line:

.then(console.log(1)) 

Calls console.log immediately, and passes the return value into the then method.

You probably want something more like the callback function in your prior line, like this:

.then(() => console.log(1))
Alexander O'Mara
  • 58,688
  • 18
  • 163
  • 171
0

The reason is that you're not passing console.log as a callback function, but you're executing it immediately and passing the returned value (undefined) to the then argument.

In the second then, you pass an anonymous function, but you're not executing it.

Like this:

function myFunction() {
    console.log("inside myFunction()");
}

function then(fnCallback) {
    console.log("inside then()");
    fnCallback();
}


then(myFunction);
    /*  Log:
        inside then()
        inside myFunction()
    */



then(() => myFunction() );
    /*  Log:
        inside then()
        inside myFunction()
    */        



then(function() { myFunction() });
    /*  Log:
        inside then()
        inside myFunction()
    */        



/* what happens here:
    1) executes myFunction(), that returns undefined
    2) executes then() with undefined as argument
    3) try to call fnCallback (which is undefined), and trows an error
*/
then(myFunction());
    /*  Log:
        inside myFunction()
        inside then()
        Uncaught TypeError: fnCallback is not a function
    */   
mrlew
  • 7,078
  • 3
  • 25
  • 28