227

I have got a javascript code like this:

function justTesting() {
  promise.then(function(output) {
    return output + 1;
  });
}

var test = justTesting();

I have got always an undefined value for the var test. I think that it is because the promises are not resolved yet..there is a way to return a value from a promise?

Priscy
  • 2,303
  • 2
  • 10
  • 6
  • 35
    the return value of a `then()` call is again a promise, which wraps the value your returned. – Sirko Dec 04 '15 at 18:17
  • You have a syntax error, I don't think this even parses. – djechlin Dec 04 '15 at 18:31
  • 9
    test is undefined because justTesting returns nothing in your example (you have no return). Add a return and test will be defined as a promise. – Jerome WAGNER Dec 04 '15 at 18:31
  • 1
    Thanks for the feedback..the point is to assign output +1 to test. – Priscy Dec 04 '15 at 18:36
  • 4
    What is the variable `promise`. You don't show it defined anywhere and you don't return anything from your `justTesting()` function. If you want better help, you need to describe what problem you're trying to solve rather than just showing us code that is so "off" that it doesn't even illustrate what you're really trying to do. Explain the problem you're trying to solve. – jfriend00 Dec 05 '15 at 00:31
  • 16
    *Ironic that every single answer tells us how to just return another promise to call.* – Andrew Aug 27 '19 at 21:20
  • 4
    **Actual answer:** https://softwareengineering.stackexchange.com/a/350041/171994 – Andrew Aug 27 '19 at 21:23
  • Isn't this where async/await clauses are used? the function would be defined as an async function, and the `promise` function would be called with an `await`? – Ryan Griggs Jan 07 '20 at 00:27
  • 1
    Does this answer your question? [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Heretic Monkey Feb 27 '20 at 22:39

8 Answers8

199

When you return something from a then() callback, it's a bit magic. If you return a value, the next then() is called with that value. However, if you return something promise-like, the next then() waits on it, and is only called when that promise settles (succeeds/fails).

Source: https://web.dev/promises/#queuing-asynchronous-actions

BinaryButterfly
  • 18,137
  • 13
  • 50
  • 91
c0ming
  • 3,407
  • 1
  • 21
  • 26
  • seem like because of this reason, then I can do promise chain for iterating array with Ajax requests synchronously in https://stackoverflow.com/q/53651266/2028440 – Bằng Rikimaru Dec 06 '18 at 13:36
  • 1
    Related [link](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then#Return_value) – Marinos An Dec 16 '19 at 14:21
  • 3
    but how does Promise.all capture the return values of each resolved promise? – noob7 Dec 29 '20 at 10:51
88

To use a promise, you have to either call a function that creates a promise or you have to create one yourself. You don't really describe what problem you're really trying to solve, but here's how you would create a promise yourself:

function justTesting(input) {
    return new Promise(function(resolve, reject) {
        // some async operation here
        setTimeout(function() {
            // resolve the promise with some value
            resolve(input + 10);
        }, 500);
    });
}

justTesting(29).then(function(val) {
   // you access the value from the promise here
   log(val);
});

// display output in snippet
function log(x) {
    document.write(x);
}

Or, if you already have a function that returns a promise, you can use that function and return its promise:

// function that returns a promise
function delay(t) {
  return new Promise(function(resolve) {
    setTimeout(function() {
      resolve();
    }, t);
  });
}

function justTesting(input) {
  return delay(100).then(function() {
    return input + 10;
  });
}

justTesting(29).then(function(val) {
  // you access the value from the promise here
  log(val);
});

// display output in snippet
function log(x) {
  document.write(x);
}
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • 3
    what throws me off is the double `return`, i.e. `justTesting` says `return.then => return`. I know this works bcs I've implemented this (bcs linting forced me to, away from `new Promise`), but can you explain how to understand/think of that return/return pair? – Ronnie Royston Sep 13 '18 at 18:13
  • 3
    @RonRoyston - First off, the function you pass to `.then()` is a separate function from the containing function so when it is called, it has its own return value. Secondly, the return value from a `.then()` handler becomes the resolved value of the promise. So, `.then(val => {return 2*val;})` is changing the resolved value from `val` to `2*val`. – jfriend00 Sep 14 '18 at 02:13
22

What I have done here is that I have returned a promise from the justTesting function. You can then get the result when the function is resolved.

// new answer

function justTesting() {
  return new Promise((resolve, reject) => {
    if (true) {
      return resolve("testing");
    } else {
      return reject("promise failed");
   }
 });
}

justTesting()
  .then(res => {
     let test = res;
     // do something with the output :)
  })
  .catch(err => {
    console.log(err);
  });

Hope this helps!

// old answer

function justTesting() {
  return promise.then(function(output) {
    return output + 1;
  });
}

justTesting().then((res) => {
     var test = res;
    // do something with the output :)
    }
Vidur Singla
  • 265
  • 3
  • 12
  • 1
    What would happen if in "//do something with the output" I put a return statement? For example: I would have the "JustTesting().then..." within a parent function. Would I be able to return a value within the "then" part? – mrzepka Sep 23 '17 at 05:06
  • 2
    If you want to return a value from //do something with the output, you will have to add a return before justTesing(). Example, " return justTesting().then((res) => { return res; }); – Vidur Singla Sep 23 '17 at 08:11
20

I prefer to use "await" command and async functions to get rid of confusions of promises,

In this case I would write an asynchronous function first, this will be used instead of the anonymous function called under "promise.then" part of this question :

async function SubFunction(output){

   // Call to database , returns a promise, like an Ajax call etc :

   const response = await axios.get( GetApiHost() + '/api/some_endpoint')

   // Return :
   return response;

}

and then I would call this function from main function :

async function justTesting() {
   const lv_result = await SubFunction(output);

   return lv_result + 1;
}

Noting that I returned both main function and sub function to async functions here.

Bulent Balci
  • 644
  • 5
  • 11
  • Right... Using await made it much cleaner as well as solved the issue – karthikeyan Jul 11 '20 at 07:52
  • perfect, but what about error if service fails? it would return promise back right? – minigeek Aug 30 '20 at 08:39
  • Hi @minigeek , you should put await command between a TRY-CATCH block for it as below : try { const lv_result = await SubFunction(output); } catch (error) { console.log("Error reading an image", error); } – Bulent Balci Aug 31 '20 at 09:54
  • 1
    It tried that but it didn't work so i ended up returning promise itself lol – minigeek Aug 31 '20 at 10:28
5

Promises don't "return" values, they pass them to a callback (which you supply with .then()).

It's probably trying to say that you're supposed to do resolve(someObject); inside the promise implementation.

Then in your then code you can reference someObject to do what you want.

Bigeyes
  • 1,508
  • 2
  • 23
  • 42
5

I think what the original poster wants is to return an unwrapped value from a promise without actually returning another promise. Unless proven otherwise, I'm afraid this is not possible outside of a then() or async/await context. You always get a promise no matter what.

Jose Quijada
  • 558
  • 6
  • 13
-3

You need to make use of reference data type like array or object.

function foo(u,n){
  let result = [];
  const userBrands = new Promise((res, rej)=> {
                        res(['brand 1', 'brand 3']);
                      })
  
  userBrands.then((ub)=>{
    return new Promise((res, rej) =>{
      res([...ub, 'brand 4', 'brand 5']);
    })
  }).then(response => {
    return result.push(...response);
  });
  return result;
};
foo();
Cijo V J
  • 261
  • 1
  • 3
  • 14
-5

You cannot return value after resolving promise. Instead call another function when promise is resolved:

function justTesting() {
    promise.then(function(output) {
        // instead of return call another function
        afterResolve(output + 1);
    });
}

function afterResolve(result) {
    // do something with result
}

var test = justTesting();
Przemek
  • 3
  • 2
  • 1
    `you cannot return a value after resolving a promise.` that's not true, see https://javascript.info/promise-chaining , here is a more accurate answer (https://stackoverflow.com/a/45482610/1681445) see `// old answer` last section code – dennisbot Jan 11 '21 at 20:20