2017-09-03 96 views
4
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> } 

为什么它不等待我的回应呢?

回答

3

为什么它不等待我的回应呢?


这很简单,因为正在返回的承诺。节点js是单线程并且以非阻塞方式执行。
这意味着,在返回响应得到功能响应变量的分辨率之前执行。
尝试如下:

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(); 

此实例也返回一个承诺,但在这种情况下,我们等待的承诺分辨率。

希望得到这个帮助。

+0

这不是我想要的。我希望函数返回响应。你是说这是无法完成的吗? – pguardiario

+2

@pguardiario无法完成。我强烈建议你首先从回调开始,在深入研究async/await等更复杂的事情之前,学习如何构造异步执行代码。 – slebetman

+0

我不明白为什么。我可以看到函数阻塞,这意味着资源在函数返回之前已经加载。那么为什么我不能直接访问它? – pguardiario

2

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

要等待结果,您可以使用await关键字来阻止,直到承诺解决。 await命令将返回承诺的结果。例如,登录get函数的结果,你可以改变最后一行:

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

UPDATE:

让我给这一次机会(对不起,如果我打一个死马在这里)。

由于您的response变量是一个异步函数,它的返回类型是一个承诺,通过定义一个异步函数。尽管ret变量正在等待,但这意味着在写入ret变量时它会被阻止。为了等待完成,需要运行response异步函数来完成。如果你想等待返回值,然后添加后处理这里的AWAIT将是有益的,但在这个例子而言,你的try块可能仅仅是:

try { 
    return request(url, _opt) 
} 

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

由于response是一种承诺,而你正在返回response,功能get也返回一个承诺。你然后试图记录这个承诺(这显然不起作用)。这就是为什么你必须await.thenget函数才能得到结果。

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

+0

不是这样。我正在等待,并没有等待。而且,await只能在异步函数中使用。 – pguardiario

+0

对不起,我不是最好的JavaScript(但我已经在C#中使用异步等待)。也许你可以尝试这样的事情:get('http://www.httpbin.org/ip').then(response => console.log(response)) –

+0

感谢您的尝试,但这并没有回答这个问题。 – pguardiario