我試著去了解 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粉0999853732023-10-20 14:57:49
非同步前綴是 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粉0020233262023-10-20 12:58:06
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
來開始工作。 new Promise
捕獲並轉換為 Promise 拒絕。 then
錯誤)都會被捕獲並轉換為拒絕。