中止包含setInterval和事件调用的异步函数

时间:2019-06-14 21:45:34

标签: javascript async-await setinterval addeventlistener

最重要的是:我不掌握异步等待并承诺语法。所以,如果我的代码段片段太短了,我感到非常抱歉。

我想调用一个函数(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()首次启动,当用户按下CTRL时等待volumeUp()解析,然后再次启动launchTestAtFrequency()以测试另一只耳朵并等待volumeUp()被启动用户按下CTRL时解决

1 个答案:

答案 0 :(得分:0)

您错过了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();
    });
}

此外,您的代码还包含控制台可能发现的错误。例如,您有两个嵌套的间隔(这是我从未见过且无法想象对任何事情有用的模式),但是内部的间隔缺少第二个参数并右括号。