Joao M
Joao M

Reputation: 684

Node.JS - Promises do not wait to resolve

I am using the dockerode for manipulate docker from node.js. The library it self is not the problem but i am have issues with PROMISE. It seems the promise do not wait to resolve.

The code below I expected the output will be:

Start
Middle // (or Err if docker does not running)
End

But I am receiving:

Start
End
Middle

It seems the promise is not waiting to continue the javascript running flow. What I am doing wrong?

const Docker = require('dockerode')
let docker = new Docker();

console.log('Start');
let promise = new Promise(function (resolve, reject) {
    docker.listContainers({all: true}, function (err, data) {
        if (err) {
            reject(err)
        } else {
            resolve(data);
        }
    });
});

promise.then(function (data) {
    console.log('Middle');
}, function (err) {
    console.log('Err');
});

console.log('End');

Copy and paste this code on https://npm.runkit.com/dockerode or see the result here: https://runkit.com/embed/y3wvg6ktecb9

Upvotes: 2

Views: 10222

Answers (1)

nem035
nem035

Reputation: 35481

Your output is correct, you're misunderstanding how promises work.

Promises are asynchronous, they run on a different (microtask) tick within the same task in the event loop. This means no promise is resolved while a synchronous piece of code is running.

// output 'a', 'c', 'b'
console.log('a');
Promise.resolve().then(() => console.log('b'));
console.log('c');

Furthermore, even if promises were synchronous, the call to docker.listContainers is asynchronous and receives a callback to call when the operation is successful.

If you want to wait for a promise, either put the code that you want to run after a promise is resolved in a then callback of that promise:

// output 'a', 'b', 'c'
console.log('a');
Promise.resolve()
   .then(() => console.log('b'))
   .then(() => console.log('c'));

Or wrap your code in an async function and await the promise:

// output 'a', 'b', 'c'
(async () => {
  console.log('a');
  await Promise.resolve().then(() => console.log('b'))
  console.log('c');
})()

Upvotes: 18

Related Questions