2017-09-03 97 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