非同步函數傳回的是 Promise,而不是值
P粉464208937
P粉464208937 2023-10-19 18:54:01
0
2
546

我試著去了解 async/await 如何與 Promise 結合使用。

async function latestTime() {
  const bl = await web3.eth.getBlock('latest');
  console.log(bl.timestamp); // Returns a primitive
  console.log(typeof bl.timestamp.then == 'function'); //Returns false - not a promise
  return bl.timestamp;
}
const time = latestTime(); // Promise { <pending> }

據我了解,await 應該是阻塞的,並且在上面的程式碼中,它似乎阻止使用原語 timestamp 返回物件 bl 。然後,我的函數傳回原始值,但是時間變數設定為待處理的承諾而不是該原始值。我錯過了什麼?

P粉464208937
P粉464208937

全部回覆(2)
P粉099985373

非同步前綴是 Promises 的一種包裝器。

async function latestTime() {
    const bl = await web3.eth.getBlock('latest');
    console.log(bl.timestamp); // Returns a primitive
    console.log(typeof bl.timestamp.then == 'function'); //Returns false - not a promise
    return bl.timestamp;
}

與相同

function latestTime() {
    return new Promise(function(resolve,success){
        const bl = web3.eth.getBlock('latest');
        bl.then(function(result){
            console.log(result.timestamp); // Returns a primitive
            console.log(typeof result.timestamp.then == 'function'); //Returns false - not a promise
            resolve(result.timestamp)
        })
}
P粉002023326

async 函數總是傳回一個 Promise。這就是它報告非同步工作完成情況的方式。如果您在另一個async函數中使用它,則可以使用await來等待其promise解決,但在非async中函數(通常在頂層或在事件處理程序中),您必須直接使用Promise,例如:

latestTime()
.then(time => {
    console.log(time);
})
.catch(error => {
    // Handle/report error
});

...不過,如果您在 JavaScript 模組的頂層執行此操作,則所有現代環境現在都支援 模組中的頂層 await

const time = await latestTime();

(請注意,如果該Promise 被拒絕,您的模組將無法載入。如果即使Promise 失敗您的模組也能有意義地工作,請務必將其包裝在try/catch 中 處理承諾拒絕。)


可能(或可能不會)以明確承諾回呼術語的形式揭示了一些事情,讓我們了解JavaScript 引擎如何在幕後處理您的async 函數:

function latestTime() {
    return new Promise((resolve, reject) => {
        web3.eth.getBlock('latest')
        .then(bl => {
            console.log(bl.timestamp);
            console.log(typeof bl.timestamp.then == 'function');
            resolve(bl.timestamp);
        })
        .catch(reject);
    });
}

一些重要的說明:

  • 您傳遞給 new Promise 的函數(promise 執行器函數)由 new Promise 同步呼叫。
    • 這就是操作開始的原因,同步呼叫web3.eth.getBlock來開始工作。
  • Promise 執行器中拋出的任何錯誤(等)都會被 new Promise 捕獲並轉換為 Promise 拒絕。
  • 在 Promise 回呼中拋出的任何錯誤(例如我們傳遞的 then 錯誤)都會被捕獲並轉換為拒絕。
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板