gpt4 book ai didi

javascript - 在异步函数中不调用回调相当于什么?

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:25:17 24 4
gpt4 key购买 nike

在 async/await 之前,当我的代码使用回调时,我可以做三件事:(1) 调用带有结果的回调,(2) 调用带有错误的回调,或 (3) 不调用回调完全没有。

案例 (3) 用于这样的情况:假设您有一个缩放按钮,用户可以单击它以更高分辨率渲染图像,这是一个异步过程。如果用户再次点击缩放按钮,那么第一个渲染就不再相关,可以取消让新的缩放级别渲染运行。我通过从函数内部返回而不调用回调来处理这个问题,例如

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

使用 async/await,你只能做两件事:return 或 throw。目前,我一直在使用 throw 来指示操作已取消,因为返回可能会错误地指示上游进程应该继续运行。但抛出的问题是所有上游调用者都需要知道它本身并不是真正的错误,因此他们可能需要检查错误的类型。

我的另一个疯狂想法是创建一个永不返回的 promise 。例如。 await never(),其中函数定义如下:

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

这相当于不调用回调。

但我不知道那样会不会一遍又一遍地泄漏内存。

有没有没有我上面提到的缺点的更好的等价物?

最佳答案

如果绝对必要,您可以等待永不返回的 promise 。这相当于不调用回调。

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

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

根据这些答案,这将被垃圾收集,因为返回的 promise 从未使用过,并且在 promise 的函数参数内没有与堆的连接。

Do never resolved promises cause memory leak?

Are JavaScript forever-pending promises bad?

但是,这很可能不是您想要做的,因为上游调用者可能想知道他们的操作已被取消。如果操作是由用户通过 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;
}
}

关于javascript - 在异步函数中不调用回调相当于什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46347384/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com