如何在没有异步/等待的情况下从待处理的已解决承诺中获取数据?

时间:2019-04-12 02:32:34

标签: javascript promise

我有抽象:

process.on('uncaughtException', (exception) => {
  // handle or ignore error
});

我想在其他代码中使用它,例如:

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

如果我if(something){ const data = fetchDataFromAPI() return data } 的数据得到解决,则有待履行承诺

console.log

如何在Promise {<pending>} __proto__: Promise [[PromiseStatus]]: "resolved" [[PromiseValue]]: Object 中而不是Promise中获得该对象?

3 个答案:

答案 0 :(得分:0)

为避免异步/等待,您需要使用另一个.then

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

答案 1 :(得分:0)

不,您不能不使用promise或async / await等,因为调用REST API是异步操作并且是非阻塞的。

当您调用REST API时,代码不应该等到API返回值之后,因为它可能会花费很多时间,从而使程序无响应,因此通过设计使网络请求被分类为:异步操作。

答案 2 :(得分:0)

Promise是一种语言构造,可使JavaScript引擎继续执行代码而无需等待内部函数(也称为执行程序)的返回。

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

console.log(p);

基本上,诺言是用于回调的美化语法糖。我们将看到如何但首先让我们拥有更现实的代码:

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

let data = someApiCall();

console.log(data);

这是所谓的异步代码,当javascript引擎执行它时,someApiCall会立即返回结果,在这种情况下是未完成的承诺:

> Promise {<pending>}

如果您注意执行程序,您将看到我们需要传递resolve和拒绝参数,也就是回调。是的,它们是直接内置在语言中的回调。当他们中的任何一个被召唤时,promise将改变其状态并因此得以解决。我们不称其为已解决,因为解决意味着成功执行,但函数也会出错。

我们如何获取数据?好吧,我们需要更多的回调,一旦实现诺言,执行者函数就会调用这些回调:

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

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

为什么我们需要传递单独的回调?因为一个将被提供给resolve回调,另一个将被拒绝。然后,回调将由解决函数调用,而回调将由拒绝函数捕获。

JavaScript引擎稍后会在闲暇时执行这些回调,对于常规函数来说,这意味着清除事件循环时,对于时间到时表示超时。

现在回答您的问题,我们如何从诺言中获取数据。好吧,我们不能。

如果您仔细观察,您会发现我们并没有真正获取数据,而是继续提供回调。没有数据输出,但是传入了回调。

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

有人说使用等待:

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

但是有一个陷阱。我们必须将其包装在异步函数中。总是。为什么?因为Async / await是在promise api之上的另一层抽象或语法糖,无论您喜欢哪个。这就是为什么我们不能直接使用await而是总是将其包装在async语句中的原因。

总而言之,当我们使用promise或async / await时,我们需要遵循某些约定,并使用紧密关联的回调编写简洁的代码。 javascript引擎或babeljs或typescript之类的编译器会将这些代码转换为可运行的常规javascript。

我能理解您的困惑,因为人们在谈论诺言时总是说要取出数据,但是我们没有取出任何数据,而是在数据准备好后传递要执行的回调。

希望现在一切都清楚了。