简体   繁体   English

如何在没有async / await的情况下从待解决的承诺中获取数据?

[英]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 如果我console.log数据我得到的是已解决的待决承诺

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

How do I get that Object in data instead of Promise? 如何在data而不是Promise中获取该对象?

To avoid async/await, you'll need to use another .then : 为了避免异步/ AWAIT,你需要使用另一个.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. 不,你不能不使用promises或async / await等因为调用REST API是一个异步操作并且是非阻塞的。

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. 当您调用REST API时,代码不应该等到API返回值,因为它可能会花费很多时间,使程序无响应,因此通过设计使网络请求被归类为异步操作。

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. Promise是一种语言结构,它使JavaScript引擎继续执行代码而无需等待内部函数的返回,也称为执行程序。

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: 这是一个所谓的异步代码,当javascript引擎执行它时,someApiCall会立即返回一个结果,在这种情况下是挂起的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. 然后通过resolve函数调用回调,通过reject函数捕获回调。

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. Javascript引擎稍后将在休闲时执行这些回调,对于常规函数,它意味着在事件循环被清除时,在时间到期时超时。

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: 有人说用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. 因为Async / await是另一个抽象级别或语法糖,无论你喜欢什么,在promise api之上。 That is why we can not use await directly but always wrap it in async statement. 这就是为什么我们不能直接使用await但总是将它包装在异步语句中。

To sum up, when we use promise or async/await we need to follow certain convention and write terse code with closely knitted callbacks. 总而言之,当我们使用promise或async / await时,我们需要遵循某些约定并用紧密编织的回调编写简洁代码。 Either javascript engine or transpilers like babeljs or typescript converts these code to regular javascript to be run. 无论是javascript引擎还是像babeljs或typescript这样的转换器都会将这些代码转换为常规的javascript来运行。

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. 我可以理解你的困惑,因为人们在谈论promises时不断说出数据,但是我们没有得到任何数据,但是在数据准备就绪时传递回调。

Hope everything is clear now. 希望现在一切都清楚了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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