1 回答

TA貢獻1825條經驗 獲得超6個贊
JS 中沒有“等待”。只有“運行代碼”和“運行代碼以響應信號”(事件、回調、承諾)。在這種情況下,您想根據無法控制其計時的進程執行某些操作,因此不能使用同步函數:當函數到達其return關鍵字時,您沒有任何信息可以返回然而..
因此,與其讓您的函數返回一個值并讓調用者等待該值,不如讓您的代碼“在輸入信息后執行操作”。也就是說,讓您的函數生成一個您注冊了處理程序的事件,或者將回調作為參數傳遞,以便您的函數在獲得必要信息后可以運行該回調,或者讓它返回一個承諾,其resolve(或reject)獲得必要信息后調用。
1. 基于事件:
const pubsub = ...;
function checkGatwayAvailability() {
request.post(url, (err, res, body) => {
pubsub.signal("gateway:availability", { available: ..., error: ... });
});
}
帶有來電者代碼:
const pubsub = ...;
pubsub.register("gateway:availability", data => {...});
...
checkGatewayAvailability();
在此,調用 this 的代碼和處理結果的代碼彼此 100% 分離。另請注意,這pubsub不是真實的。根據您的框架和 API,將有不同的方法來實現事件生成/處理,或者您甚至可能需要編寫自己的(這實際上意味著“打開 npm 并找到一個有詳細記錄并被許多人使用的方法,然后使用那個")。
2. 使用回調:
function checkGatwayAvailability(reportResult) {
request.post(url, (err, res, body) => {
reportResult({ available: ..., error: ... });
});
}
帶有來電者代碼:
checkGatwayAvailability( result => {
...
});
在這種方法中,調用和處理代碼是耦合的,即您的調用指向處理程序,即使您的處理程序聲明在完全不同的地方,例如:
checkGatwayAvailability(NetworkMonitor.handleGatewayResponse);
3. 使用承諾:
function checkGatwayAvailability(reportResult) {
return new Promise((resolve, reject) => {
request.post(url, (err, res, body) => {
if (err) reject(err);
resolve(...);
});
});
}
帶有來電者代碼:
checkGatwayAvailability().then(result => {...}).catch(err => {...});
與回調類似,調用和處理代碼是耦合的,但是通過承諾你不會“猜測”結果信息是好還是壞,你實際上有“好”案例的單獨代碼路徑(由 處理then),和“壞”案例(由 處理catch)。
3b. 通過async/await語法使用承諾:
在這種情況下,request.post不返回 Promise,您的函數仍需要烘焙自己的 Promise,因此使用async聲明沒有多大意義。不過,我們仍然可以await在調用代碼中使用關鍵字:
try {
const result = await checkGatwayAvailability();
} catch (e) {
...
}
但前提是調用者代碼本身在async上下文中運行。
添加回答
舉報