简体   繁体   中英

How do I get data from pending resolved promise without async/await?

I have abstraction:

function fetchDataFromAPI() {
  const url = `https://api...`
  return fetch(url).then(response => response.json())
}

I want to use it in my other piece of code like:

if(something){
  const data = fetchDataFromAPI()
  return data 
}

if I console.log data what I get is resolved pending promise

Promise {<pending>}
  __proto__: Promise
  [[PromiseStatus]]: "resolved"
  [[PromiseValue]]: Object

How do I get that Object in data instead of Promise?

To avoid async/await, you'll need to use another .then :

if (something) {
  return fetchDataFromAPI()
    .then((data) => data /* you can console.log(data) here */)
}

No, you cannot without using promises or async/await etc because calling a REST API is an asynchronous operation and is non blocking.

When you make a call to a REST API, the code shouldn't wait until the API returns a value because it may take a lot of time, making program non-responsive, thus by design making a network request is categorized as an asynchronous operation.

Promise is a language construct that makes JavaScript engine to continue to execute the code without waiting the return of inner function, also known as executor.

var p = new Promise(function(resolve, reject) {
  setTimeout(function() {
    resolve('foo');
  }, 300);
});

console.log(p);

Basically a promise is a glorified syntactic sugar for a callback. We will see how but first lets have a more realistic code:

function someApiCall(){
  return new Promise(function(resolve, reject){
    setTimeout(()=>{
      resolve('Hello');
    })
  })
}

let data = someApiCall();

console.log(data);

This is a so-called asynchronous code, when javascript engine executes it, someApiCall immeately returns a result, in this case pending promise:

> Promise {<pending>}

If you pay attention to the executor, you will see we needed to pass resolve and reject arguments aka callbacks. Yes they are callbacks, built right into the language. When either of them called, promise will change its state and hence be settled. We don't call it resolved because resolving implies successful execution but a function can also error out.

How do we get data? Well we need more callbacks, which will be called by the executor function once the promise settled:

var p = new Promise(function(resolve, reject) {
  setTimeout(function() {
    resolve('foo');
  }, 300);
});

p.then((result) => {
  console.log(result); // foo
}).catch((err) => {
  console.log(err);
});

Why we need to pass separate callbacks? Because one will be fed to the resolve callback, other to the reject. Then callback will be called by resolve function, catch callback by reject function.

Javascript engine will execute these callbacks later on its leisure, for a regular function it means when the event loop is cleared, for timeout when the time is up.

Now to answer your question, how do we get data out from a promise. Well we can't.

If you look closely, you will see we don't really get the data out but keep feeding callbacks. There is no getting data out, but passing callbacks in.

p.then((result) => {
  console.log(result);
}).catch((err) => {
  console.log(err);
});

Some say use await:

async function() {
  let result = await p;
}

But there is a catch. We have to or wrap it in async function. Always. Why? Because Async/await is another level of abstraction or syntactic sugar, whichever you prefer, on top of promise api. That is why we can not use await directly but always wrap it in async statement.

To sum up, when we use promise or async/await we need to follow certain convention and write terse code with closely knitted callbacks. Either javascript engine or transpilers like babeljs or typescript converts these code to regular javascript to be run.

I can understand your confusion because people keep saying getting data out when talking about promises, but we don't get any data out but pass callback to be executed when the data is ready.

Hope everything is clear now.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM