【问题标题】:Getting JavaScript promise value [duplicate]获取 JavaScript 承诺值
【发布时间】:2018-12-24 12:59:35
【问题描述】:

我有一个 json 文件,我正在尝试读取其内容以在脚本中使用。我正在使用以下内容来获取 json:

const json = fetch('Data/my_data.json').then(response => response.json());

当我这样做并查看控制台中的 json 对象时,我看到它是一个返回的 promise(已解决状态),其中包含文件中的实际 json 对象。但是,您不能直接访问 promisevalue。你必须再次使用 then 语句,所以我使用了这个:

json.then(function(getData){metaData = getData;});

元数据对象未设置为原始承诺的值。直到稍后第二次完成时才会设置它。尽管在最初返回的承诺中,该信息已经可用。

是否有可能在没有第二个 then 语句的情况下获得原始的 promisevalue 或 我是否使用第二个 then 语句错误地访问了 Promise。

感谢您的任何见解!

【问题讨论】:

标签: javascript promise fetch


【解决方案1】:

是否有可能在没有第二个 then 语句的情况下获得原始 promisevalue,或者我是否使用第二个 then 语句错误地访问了 promise。

您必须使用.then()await 才能从promise 中获取数据。数据是异步检索的,因此唯一等待将其从 Promise 中取出的方法是使用 .then()await。而且,如果使用await,它必须在async 函数内。

虽然 promises 和 async/await 有助于管理异步操作,但它们无法改变数据是异步检索且无法同步使用的事实。因此,您必须使用异步工具来获取数据。在这种情况下,即为.then()await

而且,要使用await,您必须处于支持它的环境中。现代浏览器确实支持它(并且您已经在使用fetch(),这需要一个半现代浏览器),但不是一些旧浏览器仍在使用,所以这是一个考虑因素。在这种情况下,您可能应该使用.then()


另外,请注意在此编码结构中:

json.then(function(getData){metaData = getData;});

您将数据从承诺分配给更高范围的变量的位置几乎总是一个警告信号,表明您正在尝试在您不知道的范围内使用数据数据实际可用和做错事的时间。

您可以安全使用数据的唯一范围是INSIDE .then() 处理程序或您从那里调用并将数据传递到的函数中。不要将它分配给更高的范围,然后尝试在更高的范围内盲目使用。您不会知道数据何时真正有效。您只知道 .then() 处理程序中的时间信息。

json.then(function(data){
    // use the data here
    // write the code in here that uses the data
    // or call some function here that you pass the data to
    processData(data);
});
// can't use the data here (it's not yet available)

有关此问题的进一步说明,请参阅:How do I return the response from an asynchronous call?

【讨论】:

  • @JuanMendes - await 在我的回答中已经在多个地方被提及作为一种可能性。而且,由于 OP 没有显示包含的代码以及他们试图用这些数据做什么,我们无法真正评估 await 对他们的情况有多大用处。这取决于。要点是数据永远不会同步可用。
  • +1 for " 你将数据从承诺分配给更高范围的变量几乎总是一个警告信号,表明你正试图在一个范围内使用数据你不知道数据实际可用和做错什么的时间。”
【解决方案2】:

根据此处的文档:

https://developer.mozilla.org/en-US/docs/Web/API/Response

您很可能正在寻找这种语法:

fetch('Data/my_data.json')
  .then(response => response.json())
  .then((json) => {
    console.log('this is the json data', json)
  })

Response 对象旨在帮助处理流数据响应。为了获得实际数据,您需要为您正在寻找的格式调用适当的函数。所有这些函数都返回另一个 Promise,它允许您再次链接。

如果您担心使用 Promise.then 的语法,您可以将其提取出来以执行以下操作:

  function handleResponse(json) {
    console.log('this is the json data', json)
  }

  fetch('Data/my_data.json')
    .then(response => response.json())
    .then(handleResponse)

如果您想更进一步并可以访问原始响应,它将如下所示:

function handleResponse(response) {
   console.log('response status: ', response.status)

   response.json().then((json) => {
      console.log('what should I do with this json?', json, response)
   })
}

fetch('Data/my_data.json').then(handleResponse)

归根结底,API 是为 ReadableStreams 设计的,因此在每个步骤中都使用 Promise。为了从 Fetch API 中获取您想要的数据,您必须遵守流式传输规则。

【讨论】:

    猜你喜欢
    • 2018-06-04
    • 2019-11-02
    • 1970-01-01
    • 2018-12-10
    • 2019-04-26
    • 1970-01-01
    • 2017-05-29
    • 1970-01-01
    相关资源
    最近更新 更多