1

I have read that a when you return a value from then() it gets wrapped in a Promise and gets returned as a promise. Is there a way to return just a value and NOT a promise object?

function TestPromise() {
  //someAsyncFunction returns a Promise.
  return someAsyncFunction();
}

//Assume valueFromPromise = 2;
//After the addition newValue becomes 3
//And we return 3 instead of 3 wrapped up in a Promise.

function someFunction() {
  return latestValue = TestPromise().then(valueFromPromise => {
     newValue = valueFromPromise + 1;
     return newValue;
  });
}
function main() {
  let value = someFunction();
  //Use value here to do something.
}

I know what I am asking can be achieved via async/await. But I want to properly understand Promises.

Thanks

Taimoor
  • 167
  • 3
  • 12
  • No, you can't get around async code — it's the nature of working in a single thread. You need to embrace it. Lots of info here: https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call – Mark May 13 '18 at 22:33
  • `I know what I am asking can be achieved via async/await` that's pretty much the answer,.. What problem do you have with `async / await`? – Keith May 13 '18 at 22:34
  • I don't believe it's possible to do what you're asking. I've been handling these situations by declaring `latestValue` before initiating the promise and then assigning it a value like `latestValue = newValue` in the .then – Michael Sorensen May 13 '18 at 22:45
  • I don't have an issue with async/await. I just want to understand Promises properly. – Taimoor May 14 '18 at 20:00

2 Answers2

1

It may help to realize what is happening under the hood. Promises are really just syntax sugar around the old callbacks.

function TestPromise() {
  //someAsyncFunction returns a Promise.
  return someAsyncFunction();
}

function someAsyncFunction() {
    return new Promise(function(resolve, reject) {
        fetchSomeValue()
            .then(function(someValue) {
                resolve(someValue);
            });
}

Until the Promise has called the resolve() callback, there is no way to get that data. async/await really is quite clean, I'm not sure why you would want to avoid it.

function TestPromise() {
  //someAsyncFunction returns a Promise.
  return someAsyncFunction();
}

//Assume valueFromPromise = 2;
//After the addition newValue becomes 3
//And we return 3 instead of 3 wrapped up in a Promise.

async function someFunction() {
  const valueFromPromise = await TestPromise();
  return valueFromPromise + 1;
}

async function main() {
  let value = await someFunction();
  //Use value here to do something.
}
Jack Ryan
  • 1,287
  • 12
  • 26
  • Thanks for your answer. I am not trying to avoid async/await... but trying to understand promises better. – Taimoor May 14 '18 at 20:08
1

Short answer to the question in title:

no with vanilla promises, and yes with async await.

Long answer:

Value produced from TestPromise() can only be accessed inside the subsequent .then or .catch when working with vanilla Promises.

And then itself is creating and returning a Promise Object every time you call it, so you can have your Promise resolutions for every then separate.

Say:

const p = new Promise((resolve) => {
  setTimeout(() => resolve(1), 2000);
}).then((val) => {
  console.log(val);
  return new Promise((resolve) => {
    setTimeout(() => resolve(2), 1000);
  })
}).then((val) => {
  console.log(val);
  return 3
});

p.then(console.log);

Async/Await is just a sugar over Promises and Generators which does the aforementioned for you and unwraps the promise value and passes it to you like here:

async function someFunction() {
  const valueFromPromise = /* here it passes the unwrapped value back  after await */await TestPromise();
  return valueFromPromise + 1;
}

But still async function itself is a promise, so you have to receive its value either as attaching another then to async function like this:

someFunction().then(finalValue => console.log(finalValue)

or by using it within another async function again with unwrapping through await like this:

async function outerAsyncFunction() {
  const finalValue = await someFunction();
  console.log(finalValue);
}
Karen Grigoryan
  • 5,234
  • 2
  • 21
  • 35