[英]async function - await not waiting for promise
我正在嘗試學習異步等待。 在這段代碼中 -
const myFun = () => {
let state = false;
setTimeout(() => {state = true}, 2000);
return new Promise((resolve, reject) => {
setTimeout(() => {
if(state) {
resolve('State is true');
} else {
reject('State is false');
}
}, 3000);
});
}
const getResult = async () => {
return await myFun();
}
console.log(getResult());
為什么我得到 output 作為 -
Promise { <pending> }
而不是一些價值? getResult()
function 不應該等待myFun()
function 解析它的 promise 值嗎?
如果您使用的是 async/await,則所有調用都必須使用 Promises 或 async/await。 您不能只是從同步調用中神奇地獲得異步結果。
您的最終電話需要是:
getResult().then(response => console.log(response));
或類似的東西:
(async () => console.log(await getResult()))()
您需要了解的是,async/await 不會讓您的代碼同步運行,而是讓您將其編寫為:
簡而言之:前面帶有 async 的函數實際上是異步執行的,因此使用了關鍵字“async”。 並且“await”關鍵字將使在此異步函數中使用它的那行在其執行期間等待承諾。 因此,盡管線路等待,但整個函數仍然異步運行,除非該函數的調用者也“等待”......
更詳細的解釋:當你把 async 放在一個函數前面時,實際上是讓它返回一個帶有該函數返回的任何內容的 Promise。 該函數異步運行,當執行 return 語句時,promise 會解析返回值。
意思是,在您的代碼中:
const getResult = async () => {
return await myFun();
}
函數“getResult()”將返回一個 Promise,一旦它完成執行就會解決。 所以 getResult() 函數內的行是異步運行的,除非你告訴調用 getResult() 的函數也為它“等待”。 在 getResult() 函數中,您可能會說它必須等待結果,這使得 getResult() 的執行等待它解決 promise,但 getResult() 的調用者不會等待,除非您也告訴調用者“等待” '。
所以一個解決方案是調用:
getResult().then(result=>{console.log(result)})
或者在另一個函數中使用時,您可以簡單地再次使用“等待”
async callingFunction(){
console.log(await(getResult());
}
這是我使用帶有解析和拒絕機制的Promise處理等待和異步的例程
// step 1 create a promise inside a function
function longwork()
{
p = new Promise(function (resolve, reject) {
result = 1111111111111 // long work here ;
if(result == "good"){
resolve(result);
}
else
{
reject("error ...etc")
}
})
return p
}
// step 2 call that function inside an async function (I call it main)and use await before it
async function main()
{
final_result = await longwork();
//..
}
//step 3 call the async function that calls the long work function
main().catch((error)=>{console.log(error);})
希望可以節省一些寶貴的時間
在實際情況下,異步和等待沒有意義:
Promise.resolve(3).then(console.log); console.log(4);
4
3
換句話說,由於 then() fork 和運行比后續語句慢(即使對於已解決的 Promise),那么我們需要將后續語句放在 then 中,例如:
Promise.resolve(3).then(_ => { console.log(_); console.log(4); });
3
4
既然這是真的,那為什么還要等待。 所以我還沒有看到為什么 async 和 await 存在。
本次討論中未提及的是該行為的用例含義。 在我看來,關鍵是要考慮您打算從頂層對 output 做什么,真正異步的 function,以及您打算在哪里做。
如果您計划立即使用 output,即在等待頂級異步 function 返回的“異步”function 中,並且您對 output 所做的操作對調用堆棧中更深層的其他函數沒有任何影響,那么它更深層次的功能已經轉移並不重要。 但是如果 output 需要在調用堆棧的更深處,那么您需要使用“異步”函數在堆棧中一直等待調用到該點。 一旦您到達調用堆棧中 function 不關心異步 output 的點,您就可以停止使用異步函數。
例如,在下面的代碼中,function B 使用從 function A 返回的內容,因此被聲明為“async”並等待 A()。 Function C() 調用 B(),返回 Promise,但可以在 promise 解析之前直接繼續,因為它對 A() 的內容不感興趣,也不關心它做了什么。 所以C不需要聲明為async,也不需要await B()。
function A() {
return new Promise((resolve, reject) => {
//do something slow
resolve (astuff)
}
}
async function B() {
var bstuff = await A();
dosomethingwith(bstuff);
return;
}
function C() {
B();
dontwaitmoveon();
...
return;
}
在下一個示例中,C() 確實使用了 A() 的內容,因此需要等待它。 C() 必須聲明為“異步”並等待 B()。 然而 D() 不關心 A() 的東西,也不關心它做了什么,所以一旦 C() 返回它的 promise 就繼續前進。
function A() {
return new Promise((resolve, reject) => {
//do something slow
resolve (astuff)
}
}
async function B() {
var bstuff = await A();
dosomething();
return bstuff;
}
async function C() {
var cstuff = await B();
dosomethingwith(cstuff);
...
return;
}
function D() {
C();
dontwaitmoveon();
...
return;
}
自從弄清楚這一點后,我嘗試設計我的代碼,以便盡可能接近源使用異步 function 返回的內容。
盡管您的“ getResult ”函數是異步的,並且您正確地對 myFun 進行了 await 調用,但請查看調用getResult函數的位置,它位於任何異步函數之外,因此它是同步運行的。
所以既然getResult是從同步的角度調用的,那么只要調用,Javascript 就會同步獲取當前可用的任何結果,這是一個 Promise。
因此,異步函數的返回不能被強制等待(非常重要),因為它們與調用的來源地是同步的。
要獲得您想要的,您可以運行以下命令,
async function getResult() {
const result = await myFun();
console.log(result);
//see no returns here
}
getResult();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.