Прервать асинхронную функцию, которая содержит setInterval с eventcall - PullRequest
0 голосов
/ 15 июня 2019

Ничего страшного: я не справляюсь с асинхронным ожиданием и обещает синтаксис. Так что мне очень жаль, если мой фрагмент кода - кусок дерьма ...

Я хочу вызвать функцию (launchTestAtFrequency), которая запускает интервал и ожидает события пользователя, чтобы остановить этот интервал, и снова запустить функцию launchTestAtFrequency.

Я читал об Promise и Async-Await и попробовал сам. Но это как "аааааа ????"

Это приложение должно быть легким, чтобы я не мог использовать jQuery или другие библиотеки JS.

var oscillator;
var panner;
var volume;
var leftOrRight; // 0 = left ; 1 = right;
var interval;
var user_hearing; // set to 1 when user is hearing something

document.addEventListener('keydown', function(e) { if(e.ctrlKey) { CTRL_Parse(e) }})

function CTRL_Parse(e) { // Filter eventHandler to parse if it's left or right CTRL which is pressed
    e.preventDefault();
    if(e.location == 1) left_hearing();
    else if(e.location == 2) right_hearing();
}

function left_hearing() { // What to do when user say "i'm hearing on my right ear"
    user_hearing = 1;
}

function right_hearing() { // What to do when user say "i'm hearing on my right ear"
    user_hearing = 1;
}

async function launchTestAtFrequency(leftOrRight, frequency = 440) {
    oscillator.frequency.value = frequency;
    (leftOrRight) ? panner.setPosition(+3, 0, 0) : panner.setPosition(-3, 0, 0); // Set panner to left or right ear
    return await volumeUp(); // Return the volume for measuring the hearing evaluation
}

async function volumeUp () {
    interval = setInterval(function () {                // Volume up the sound from 0 to 0.5
        interval = setInterval(function () {
        if (volume.gain.value >= 0.5 || user_hearing) { // Stop when user is hearing something or if volume >= 0.5 (= fail)
            clearInterval(interval);
            return volume.gain.value;
        } else {
            volume.gain.value += .005;
        }
    }, 250);
}

async function launchTestAtFrequency(leftOrRight, frequency = 440) { // Just intializing the oscillator/panner then start volumeUp()
        oscillator.frequency.value = frequency;
        (leftOrRight) ? panner.setPosition(+3, 0, 0) : panner.setPosition(-3, 0, 0);
        return await volumeUp(); // Need to resolve volumeUp before continue to the next ear
}

function callPreview() {
    var reverse = (leftOrRight) ? 0 : 1;
    launchTestAtFrequency(leftOrRight).then(launchTestAtFrequency(reverse)); // Need to be called twice, once with leftOrRight at 0 or 1, then reverse (1 or 0)
}

Я ожидаю, что launchTestAtFrequency () будет запущен в первый раз, подождите, пока volumeUp () будет разрешен, когда пользователь нажимает CTRL, затем запустите launchTestAtFrequency () во второй раз, чтобы проверить другое ухо, и дождитесь, пока VolumeUp () будет разрешить, когда пользователь нажимает CTRL

1 Ответ

0 голосов
/ 15 июня 2019

Вам не хватает важной связи между await и ожидаемой вещью: это должно быть обещание.

Если это не обещание, оно неявно преобразуется в одно (то, которое мгновенно разрешается).Это то, что происходит в вашем случае, и поэтому ожидание не происходит.

Обратите также внимание, что функция ожидания (launchTestAtFrequency()) должна быть асинхронной, а не функция, которая возвращает ожидаемое значение (volumeUp()).

Упрощенная версия вашего кода может выглядеть следующим образом:

async function launchTestAtFrequency() {
    return await volumeUp(); //<-- need to ensure volumeUp() returns a promise
}

function volumeUp() {
    return new Promise(resolve => { //<-- return promise to await
        if (1 || 2)
            resolve();
    });
}

Кроме того, ваш код содержит ошибки, которые были бы обнаружены консолью.Например, у вас есть два вложенных интервала (это шаблон, который я никогда не видел и не могу себе представить, чтобы он был полезен для чего-либо), но во внутреннем отсутствует второй аргумент и закрывающие скобки.

...