0

Ожидание завершения асинхронной задачи

13

Я взаимодействую с сторонней библиотекой JavaScript, где некоторые вызовы функций являются асинхронными. Вместо того, чтобы интегрировать асинхронную логику в моё приложение, я решил написать синхронные обертки для этих асинхронных вызовов. Я понимаю, что это ужасный дизайн, но это демонстрационный проект, который, скорее всего, будет переписан. Мне нужно показать команде концепцию, а производительностью на данном этапе особо не переживать.

Вот что я хочу сделать:

function sync_call(input) {
    var value;

    // Предполагаем, что асинхронный вызов всегда успешен
    async_call(input, function(result) {value = result;} );

    return value;
}

Я пробовал использовать jQuery's deferred и promise, но, похоже, они ориентированы на асинхронный дизайн. Я хочу использовать синхронную модель в моём коде.

2 ответ(ов)

0

Вместо того чтобы возвращать значение в функции sync_call(), вы можете вызывать другую функцию непосредственно в вашем коллбэке. Это позволит вам работать с результатом асинхронного вызова сразу после его завершения, не дожидаясь возвращения значения. Примерно так:

function sync_call(input) {
    // Предположим, что асинхронный вызов всегда успешен
    async_call(input, function(result) {
        use_value(result); // Вызываем use_value сразу, когда получили результат
    });
}

Таким образом, вы убираете необходимость в переменной value, а вся логика обработки результата остается в коллбэке. Это более идиоматичный подход в JavaScript, который лучше справляется с асинхронностью.

0

Вот работающий пример, как это сделать:

function testAsync(){
    return new Promise((resolve, reject) => {
        // Здесь должна быть реализована наша функция
        setTimeout(() => {
            console.log("Привет изнутри функции testAsync");
            resolve();
        }, 5000);
    });
}

async function callerFun(){
    console.log("Вызов");
    await testAsync();
    console.log("После ожидания");
}

callerFun();

Этот код выводит:

Вызов
Привет изнутри функции testAsync
После ожидания

Чтобы сделать реализацию более полной, стоит добавить обработку ошибок (обработку случая с reject()). Вот пример с добавлением обработки ошибок:

function testAsync(){
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log("Привет изнутри функции testAsync");
            // Для теста выбросим ошибку
            const errorOccurred = false; // замените на true, чтобы сгенерировать ошибку
            if (errorOccurred) {
                reject(new Error("Произошла ошибка"));
            } else {
                resolve();
            }
        }, 5000);
    });
}

async function callerFun(){
    console.log("Вызов");
    try {
        await testAsync();
        console.log("После ожидания");
    } catch (error) {
        console.error("Ошибка:", error.message);
    }
}

callerFun();

Теперь, если в функции testAsync произойдет ошибка и вызовется reject, она будет поймана в блоке catch, и мы получим соответствующее сообщение об ошибке.

Для других примеров, смотрите здесь: https://www.delftstack.com/howto/javascript/javascript-wait-for-function-to-finish/

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь