20

EDITED as comment to duplicate I quote from: [How do I return the response from an asynchronous call?

Promises are containers for future values. When the promise receives the value (it is resolved) or when it is cancelled (rejected), it notifies all of its "listeners" who want to access this value.

This question is about how to return the value contained in the promise. The answer was useful to me, because it clarified that it is not possible to return the value, rather to access the value within the promise function.

Other useful sources about the subject, here:

Below the original question:


Could you please help in understanding how to get the value from a promise and differences between these two examples ?

//I have a simple ajax call like:

var fetch = function(start_node, end_node) {
var apiEndpoint = 'localhost/nodes/';
var loadurl = apiEndpoint+start_node+'/'+end_node;
return $.ajax({
    url: loadurl,
    type: 'GET',
    dataType: 'json',
    jsonpCallback: 'json'

  });

};
// Then I processed results in something like:
    var getResult = function(data) {
      // do smtg with data
      var result = {'myobject' : result_from_data}
      return result
    }

And finally I want to assign it results.

The following works, but I think it wastes the concept of the promise since result is assigned to a global variable declared before it:

var r;  
fetch('val1','val2')
.then(function(data){
  r = getResult(data);
})

Instead the following assigns the promise function to res.

var res = fetch('val1','val2')
.done(function(data){
  return getResult(data);
})

Could you clarify how to pass the resulting 'myobject' to the variable res, and not the promise itself?

I also tried:

var res = $.when(fetch('val1','val2'))
.done(function(data){
  return getResult(data);
})

but no success.

Community
  • 1
  • 1
user305883
  • 1,635
  • 2
  • 24
  • 48
  • 1
    I think this is a misunderstanding. There is no value to return, until the promise (asynchronous event) has been carried out. Which is expected to be later. The question then is - what would happen to this variable once assigned? Could you consider your design in terms of events and callbacks? – Danny Staple Sep 16 '15 at 15:32
  • 3
    You can't do what you're trying to do. Async is async - the result is simply not available until some time LATER, long after your function has already returned. You must put the code that uses your result INSIDE the completion callback function or call some function from within that callback and pass the data as an argument. All those other answers you reference tell you that too. You're apparently just not believing it. – jfriend00 Sep 16 '15 at 15:32
  • 1
    Show us where you are going to *use* the `res` with that `myobject` thing. What you are trying to do is exactly the thing you did with that global `r` variable - and indeed, it wastes the concept of promises and might not work in edge cases. You should just be doing `fetch(…).then(getResult).then(function(res) { … });` – Bergi Sep 16 '15 at 18:26

1 Answers1

11

You have to use the global variable trick, or accept use save-as-a-promise trick.

var getStuff = $.when(req1,req2).then(function(data1,data2) { return data1.concat(data2); });

//the variable getStuff is now a promise and any .then chained 
//to it will have data1.concat(data2) passed to it as an argument

getStuff
  .then(function(data1Data2) {
    console.log(data1Data2);
  });

//the next time you want to use it, you have to use the same promise-interface with .then
getStuff
  .then(function(data1Data2) {
    console.log(data1Data2);
  });
Adam Jenkins
  • 51,445
  • 11
  • 72
  • 100
  • 1
    Thank you! So the only way it to use the variable inside the promise itself. – user305883 Sep 16 '15 at 20:57
  • Thank you! So it is possible to access the value of the promise, only inside the promise itself. A little further: @Adam, I run the `getStuff .then(function(data1Data2) { console.log(data1Data2); }); ` in the browser console, and it returns both the value and _the promise itself_. (e.g.: ` Object {'myobject' : result_from_data}, Object {}` Could you explain why? – user305883 Sep 16 '15 at 21:06
  • 2
    It doesn't return both the value and the promise itself - that statement returns the promise (which the browser console logs) and it also `console.log`'s the data which is why you see two logs. Your two options are, as you said - use a global variable, or simply store the promise and always access it's data via a `.then` – Adam Jenkins Sep 16 '15 at 22:07
  • I do it like this: 1) Put your code inside a function that returns a promise, `promiseFunction()` 2) create an async function and put this inside: `const varName = await promiseFunction().then((done) => { return done; }).catch((err) => { throw new Error(\`RADICAL ERROR: ${err}\`); });` – agm1984 Jul 14 '17 at 02:32