簡體   English   中英

在異步函數中不調用回調等效於什么?

[英]What is the equivalent of not calling a callback when inside an async function?

在異步/等待之前,當我的代碼使用回調時,我能夠做三件事:(1)使用結果調用回調,(2)使用錯誤調用回調,或者(3)完全不調用回調。

情況(3)用於以下情況:假設您有一個縮放按鈕,並且用戶可以單擊它來以更高的分辨率渲染圖像,這是一個異步過程。 如果用戶再次單擊縮放按鈕,則第一個渲染不再相關,可以取消以使新的縮放級別渲染運行。 我通過從函數內部返回而不調用回調來處理此問題,例如

if (process.wasCanceled()) {
  return;
}
// ...
callback(someResult);

使用async / await,您只能做兩件事:返回或拋出。 當前,我一直在使用throw指示操作已取消,因為返回可能錯誤地指示上游進程應繼續運行。 但是拋出的問題是,所有上游調用者本身都需要知道這實際上不是錯誤,因此他們可能需要檢查錯誤的類型。

我的另一個瘋狂想法是創造一個永遠不會回報的承諾。 例如await never() ,其中函數定義如下:

async function never () {
    return new Promise(function () {});
}

這相當於不調用回調。

但是我不知道那是否會一遍又一遍地泄漏內存。

有沒有上面提到的缺點的更好的等效方法?

如果絕對必要,您可以等待一個永遠不會返回的承諾。 這相當於不調用回調。

async function never () {
    return new Promise(function () {});
}

async function op (process) {
    // ...
    if (process.wasCanceled()) await never();
    // ...
}

根據這些答案,這將被垃圾回收,因為從不使用返回的promise,並且promise的function參數內部沒有與堆的連接。

永不解決的承諾會導致內存泄漏嗎?

JavaScript永遠待定的承諾是否不好?

但是,這很可能不是您想要執行的操作,因為上游呼叫者可能想知道其操作已被取消。 如果操作是由用戶通過UI啟動的,那么可以,在不通知調用方的情況下取消操作可能沒問題,但是,如果該操作是通過編程方式啟動的,並且已通過其他方式(例如,由用戶取消),則調用代碼可能需要知道以便它可以重試或清理資源。

因此,解決方案是拋出特定類的錯誤,以便調用者可以檢測到該進程已取消。 例如

class ProcessCanceledError extends Error {
    ...
}

async function render (process) {
    while (...) {
        // do some rendering
        await delay(20);
        if (process.wasCanceled()) throw new ProcessCanceledError();
    }
}

var zoomProcess;

async function zoom () {
    let process = new Process();
    if (zoomProcess != null && !zoomProcess.isDone()) {
        zoomProcess.cancel();
    }
    try {
        await render();
    } catch (e) {
        // or you could do e.process === process
        if (e instanceof ProcessCanceledError &&
            process.wasCanceled() // make sure it was actually ours
        ) {
            // this assumes we are a top level function
            // otherwise, you would want to propagate the error to caller's caller
            return;
        }
        throw e;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM