【问题标题】:Await response without Async Function?等待没有异步功能的响应?
【发布时间】:2020-11-21 02:20:31
【问题描述】:

是否可以在函数中等待异步函数的响应,而不使整个函数异步,ala await 没有异步,或类似的东西? 一个例子:

const axios = require('axios');
const converter = require('number-to-words');
const formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
});
function dataFetch() {
    //fetches current exchange rate of NOK to USD
    let data = await axios.get('https://api.exchangeratesapi.io/latest?base=NOK');
    //fetches current value of Norwegian Oil fund
    let res = await axios.get('https://www.nbim.no/LiveNavHandler/Current.ashx');
    //extracts value of Norwegian Oil Fund from response data, and converts it to USD in real time.
    let dolla = (res.data.Value.replace(/\s/g, '') * data.data.rates.USD).toFixed(2);
    //Converts Basic number to number with commas, and a dollar sign.
    let val = formatter.format(dolla);
    //Generates word format of number(i.e. one hundred instead of 100)
    let str = converter.toWords(dolla);
    //Generates word format of cents.
    let cents = converter.toWords(dolla.split('.')[1].substring(0, 2));
    //Returns JSON of commaed value and full word string
    return {num: val, word: `${str} dollars and ${cents} cents`};
}
console.log(dataFetch().val);

我想确保 dataFetch() 返回的值是从 get 请求接收到的数据的处理版本,而不是一个承诺,或者 null 以便console.log() 打印出基金的价值美元,而不是 undefined、null 或其他东西。

几乎可以肯定有一个简单的解决方案,但我似乎找不到它,而且它已经破坏了我一直在研究的代码。

更新:更新以添加问题的上下文。我为我稍微不清楚的 cmets 道歉。

【问题讨论】:

  • 不,这是不可能的(没有涉及阻塞子进程的大量黑客攻击)。您需要学习如何异步编程。此外,您永远都不想阻塞 nodejs 服务器,因为它会破坏您的服务器可扩展性。如果您在函数中异步获取结果,则永远不会直接从函数返回该值,因为该函数将在您获得该值之前返回。因此,您将通过 Promise、回调或事件返回异步值。这就是 Javascript 中异步 I/O 的工作原理。
  • 如果您展示了您要解决的问题的更大背景,那么这里的人们可能会帮助您展示如何使用异步 I/O 正确编码。
  • 感谢您的回复,jfriend00,我试图用更多的实际代码来充实我的问题,以表明我的目标是什么。我提前为稍微草率的 cmets 道歉,因为我不是最擅长按照我在脑海中听到的方式格式化我的 cmets。

标签: node.js async-await


【解决方案1】:

您在 dataFetch() 函数中进行了多个异步 (axios) 调用。这意味着您的函数将在任何这些异步操作完成之前返回,您对此无能为力。这就是 Javascript 中异步操作的工作方式。因此,您不能从函数返回最终值。您的函数在知道最终值之前返回。

返回最终值有三种选择:

  1. 承诺
  2. 回调
  3. 事件

选择其中之一。

在这种情况下,自然契合将是一个承诺。无论如何,您必须将您的dataFetch() 函数声明为async,这样您就可以调用其中的await。这意味着它已经自动返回了一个承诺。然后要从 dataFetch() 获取值,您可以在返回的 Promise 上使用 await.then()

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

这就是 Javascript 中异步编程的工作原理。

【讨论】:

    【解决方案2】:

    利用我收到的答案,这是我使用的代码:

    function bimFetch() {
        axios.get('https://api.exchangeratesapi.io/latest?base=NOK').then(data => {
            axios.get('https://www.nbim.no/LiveNavHandler/Current.ashx').then(res => {
                let dolla = (res.data.Value.replace(/\s/g, '') * data.data.rates.USD).toFixed(2);
                let val = formatter.format(dolla);
                let str = converter.toWords(dolla);
                let cents = converter.toWords(dolla.split('.')[1].substring(0, 2));
                if(dolla.split('.') === '01')
                    currentStatus = { num: val, word: `${str} dollars and ${cents} cent` };
                else
                    currentStatus = { num: val, word: `${str} dollars and ${cents} cents` };
            });
        });
    }
    

    一旦提取和格式化都完成后,它会将其响应输出到currentStatus。我设置了一个setTimeout(),它会在等待大约 5 秒后通过所有连接的 WebSocket 发送一条更新状态的消息。

    我要感谢@jfriend00 在这个问题上的帮助,因为我在 JS 异步编码方面学到了宝贵的一课。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-06
      • 1970-01-01
      • 2011-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-22
      • 2017-10-18
      相关资源
      最近更新 更多