Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Error with javascript promise and then condition

I’m learning Javascript promises and thens, and am confused with this error using Node.js.

I would like dostart() to wait until nonblocking sleep is finished, and then return "Resolved" to the main func when it is done.

I get this error:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

dostart().then(value => {
         ^
TypeError: Cannot read properties of undefined (reading 'then')

Help appreciated 🙂

function nonBlockingSleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

function dostart() {
  console.log("Hello2");

  nonBlockingSleep(2000).then(() => {
    console.log("Done");
    return Promise.resolve("Resolved");
  });
}

dostart().then(value => {
  // main func - I'd like console.log to show "Resolved" when dostart() is finished
  console.log(value);
})

>Solution :

dostart isn’t async and doesn’t return the promise from then, so you can’t try to consume that promise where you call it.

You have at least a couple of options.

The simple one in this particular case is to return the promise from then:

function nonBlockingSleep(ms) {
    return new Promise((resolve) => setTimeout(resolve, ms));
}

function dostart() {
    console.log("Hello2");

    // *** Return the promise
    return nonBlockingSleep(2000).then(() => {
        console.log("Done");
        // *** There's no need for `Promise.resolve` here, `then`
        // _always_ returns a promise, and will use the return value
        // here to fulfill it. (If you return a promise instead, it will
        // resolve its promise to the promise you return instead of
        // fulfilling its promise.)
        return "Fulfilled";
    });
}

dostart().then((value) => {
    // main func - I'd like console.log to show "Resolved" when dostart() is finished
    console.log(value);
});

Your other option is to use async/await:

function nonBlockingSleep(ms) {
    return new Promise((resolve) => setTimeout(resolve, ms));
}

// *** Make `dostart` an `async` function
async function dostart() {
    console.log("Hello2");

    // *** `await` the promise from `nonBlockingSleep`
    await nonBlockingSleep(2000);
    console.log("Done");
    // *** Return the fulfillment value for this function's promise
    return "Fulfilled";
}

dostart().then((value) => {
    // main func - I'd like console.log to show "Resolved" when dostart() is finished
    console.log(value);
});

Side note: I changed "Resolved" to "Fulfilled" because we’re fulfilling the promise in that particular case. It’s common, but incorrect, to use "resolve" for "fulfill." It’s true that fulfilling a promise resolves it, but the converse isn’t true — resolving a promise doesn’t always fulfill it. It might leave it pending, or even eventually reject it, if you resolve it to another promise. I’ve written up promise terminology in this blog post.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading