【问题标题】:Why does await function return pending promise为什么等待函数返回待处理的承诺
【发布时间】:2017-09-03 12:12:37
【问题描述】:
let request = require('request-promise')

function get(url) {
  let _opt = {}
  let response = (async () => {
    try {
      var ret = await request(url, _opt);
      return ret;
    } catch (e) {
      console.log(e)
    }
  })();
  return response
}

console.log(get('http://www.httpbin.org/ip'))

给予:

Promise { <pending> }

为什么不等待我的回复?

【问题讨论】:

    标签: node.js async-await


    【解决方案1】:

    为什么不等待我的回复?


    这很简单,因为您正在返回一个承诺。 Node js 是单线程的,以非阻塞方式执行。
    这意味着 get 函数中的 return responseresponse 变量 解析之前执行。
    尝试如下:

    let request = require('request-promise')
    
    function get(url) {
        let _opt = {}
        return request(url, _opt);
    }
    
    async function some () {
        console.log(await get('http://www.httpbin.org/ip'));
    }
    
    some();
    

    这个例子也返回了一个promise,但是在这个例子中,我们等待解决promise。

    希望对您有所帮助。

    【讨论】:

    • 这不是我想要的。我希望函数返回响应。你是说这不能做吗?
    • @pguardiario 做不到。我强烈建议您先从回调开始,并在深入研究更复杂的事情(如 async/await)之前学习如何构建异步执行代码。
    • 我不明白为什么。我可以看到函数是阻塞的,这意味着资源在函数返回之前已经加载。那为什么我不能直接访问呢?
    【解决方案2】:

    异步函数是非阻塞的,并且会立即返回一个 Promise 而不是等待结果。例如,这允许多个异步函数同时运行,而不是每个函数按顺序运行。

    要等待结果,你可以使用 await 关键字来阻塞直到 promise 被解决。 await 命令将返回 promise 的结果。例如,要记录 get 函数的结果,可以将最后一行更改为:

    console.log(await get('http://www.httpbin.org/ip'))
    

    更新:

    让我再试一次(对不起,如果我在这里打败了一匹死马)。

    由于您的 response 变量是一个异步函数,因此它的返回类型是异步函数定义的承诺。即使 ret 变量处于等待状态,这仅意味着它将在写入 ret 变量时阻塞。 response async 函数需要运行完成才能等待完成。如果您想等待返回值然后添加后处理,则此处的 await 会很有用,但在此示例中,您的 try 块可能只是:

    try {
        return request(url, _opt)
    }
    

    由于request 已经返回了一个承诺,额外的等待会导致微不足道的开销,因为它隐式地创建了一个额外的承诺。

    由于response 是一个promise,而您返回的是response,函数get 也返回了一个promise。然后你试图记录这个承诺(这显然不起作用)。这就是为什么您必须 await.then get 函数才能获得结果的原因。

    来源:https://medium.com/@bluepnume/learn-about-promises-before-you-start-using-async-await-eb148164a9c8 在“陷阱 1:不等待”下

    【讨论】:

    • 不是这样的。我正在使用等待,它没有等待。另外,await 只能在异步函数中使用。
    • 抱歉,我不是最擅长 javascript(但我在 C# 中使用过 async-await)。也许你可以尝试这样的事情:get('httpbin.org/ip').then(response => console.log(response))
    • 感谢您的尝试,但这并不能回答问题。
    • 我在过去的一个小时里研究并用一些可能有用的信息更新了我的答案。如果这仍然没有帮助,我深表歉意。
    • 那么我如何在不使用回调的情况下让我的代码工作呢?
    猜你喜欢
    • 2020-12-18
    • 2021-01-02
    • 1970-01-01
    • 2019-04-29
    • 2021-07-22
    • 1970-01-01
    • 1970-01-01
    • 2020-12-20
    相关资源
    最近更新 更多