What is equivalent to not calling the callback inside the async function?

Before async / await, when my code used callbacks, I could do three things: (1) call the callback with the result, (2) call the callback with an error, or (3) not call the callback at all.

Case (3) was used in such situations: let's say you have a zoom button, and the user can click it to display a higher resolution image, and this is an asynchronous process. If the user presses the zoom button again, the first render is no longer relevant and can be canceled to start rendering a new zoom level. I handled this by returning from within a function without calling a callback, for example.

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

With async / wait, you can only do two things: return or throw. I am currently using throw to indicate that the operation has been canceled, since a return may falsely indicate that upstream processes should continue to work. But the problem with throwing is that all of the above subscribers should know that this is really not an error, and therefore, you may need to check the type of error.

Another crazy idea is to create a promise that will never come back. For instance. await never()where the function is defined as follows:

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

This is a kind of equivalent non-calling callback.

But I do not know if it will just be a memory leak again and again.

Is there a better equivalent without the disadvantages mentioned above?

+4
1

, , . .

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

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

, , .

promises ?

JavaScript promises ?

, , , , , . , , , , , - , . , , , , .

, , . .

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 caller
            return;
        }
        throw e;
    }
}
+1

Source: https://habr.com/ru/post/1686142/


All Articles