使用setTimeout时代码不起作用

时间:2017-01-23 15:27:53

标签: javascript jquery webkitspeechrecognition

我正在尝试编写一个可以使用语音输入的代码,并且基于输入可以迁移到另一个页面。 当使用超时并且没有超时时,我的代码没有等待,代码不等待输入。 HTML页面

<script src="Content/SpeechRecognisation.js" type="text/javascript"></script>
    <script src="Content/SpeechUtterance.js" type="text/javascript"></script>
    <script src="Content/LoginScript.js" type="text/javascript"></script>
    <script src="Content/Additional.js" type="text/javascript"></script>
    <title>Login Screen</title>
    <meta charset="utf-8" />
</head>

<body onload="Typer()"></body>
Js文件中的

Javascript代码

function LoginPageSpeech() {
    pageName = 'LoginPage';
    controlPointer = "1";
    var CPR_No = final_transcript;
    $("#txtCPRNo").val(final_transcript);
    var pageDetail = "Entered CPR Number is " + final_transcript;
    CustomerResponse = final_transcript;
    speak(pageDetail);
    setTimeout(function(){},4000);
    speak("if details are correct ,please say yes else say no after beep");
    setTimeout(function () { SoundMake(); }, 4000);
    setTimeout(function() {startDictation(event);},3000);
    setTimeout(function() { },4000);
    if (final_transcript == "YES") {
        setTimeout(AuthenticationMsg,7000);
    }
    else
    {
//        setTimeout(function () { speak("Sorry.Please repeat again after beep"); }, 4000);
//        setTimeout(function () { SoundMake(); }, 3000);
//        setTimeout(function () { startDictation(event); }, 3000);
//        
//        LoginPageSpeech();
    }
}


function Typer() {
    pageName = "LoginPage";
    speak('Welcome ,Please Speak your CPR Number after a beep');

    setTimeout(function () { SoundMake(); }, 4000);
    timeOutValue = 9000;
    setTimeout(function () { startDictation(event); }, 4000);

}
function SoundMake() {
    var snd = new Audio("data:audio/wav;base64,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qJrx4KOQjahZxWbcZgztj2c49nKmkId44S71j0c8eV9yDK6uPRzx5X18eDvjvQ6yKo9ZSS6l//8elePK/Lf//IInrOF/FvDoADYAGBMGb7FtErm5MXMlmPAJQVgWta7Zx2go+8xJ0UiCb8LHHdftWyLJE0QIAIsI+UbXu67dZMjmgDGCGl1H+vpF4NSDckSIkk7Vd+sxEhBQMRU8j/12UIRhzSaUdQ+rQU5kGeFxm+hb1oh6pWWmv3uvmReDl0UnvtapVaIzo1jZbf/pD6ElLqSX+rUmOQNpJFa/r+sa4e/pBlAABoAAAAA3CUgShLdGIxsY7AUABPRrgCABdDuQ5GC7DqPQCgbbJUAoRSUj+NIEig0YfyWUho1VBBBA//uQZB4ABZx5zfMakeAAAAmwAAAAF5F3P0w9GtAAACfAAAAAwLhMDmAYWMgVEG1U0FIGCBgXBXAtfMH10000EEEEEECUBYln03TTTdNBDZopopYvrTTdNa325mImNg3TTPV9q3pmY0xoO6bv3r00y+IDGid/9aaaZTGMuj9mpu9Mpio1dXrr5HERTZSmqU36A3CumzN/9Robv/Xx4v9ijkSRSNLQhAWumap82WRSBUqXStV/YcS+XVLnSS+WLDroqArFkMEsAS+eWmrUzrO0oEmE40RlMZ5+ODIkAyKAGUwZ3mVKmcamcJnMW26MRPgUw6j+LkhyHGVGYjSUUKNpuJUQoOIAyDvEyG8S5yfK6dhZc0Tx1KI/gviKL6qvvFs1+bWtaz58uUNnryq6kt5RzOCkPWlVqVX2a/EEBUdU1KrXLf40GoiiFXK///qpoiDXrOgqDR38JB0bw7SoL+ZB9o1RCkQjQ2CBYZKd/+VJxZRRZlqSkKiws0WFxUyCwsKiMy7hUVFhIaCrNQsKkTIsLivwKKigsj8XYlwt/WKi2N4d//uQRCSAAjURNIHpMZBGYiaQPSYyAAABLAAAAAAAACWAAAAApUF/Mg+0aohSIRobBAsMlO//Kk4soosy1JSFRYWaLC4qZBYWFRGZdwqKiwkNBVmoWFSJkWFxX4FFRQWR+LsS4W/rFRb/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////VEFHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU291bmRib3kuZGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMjAwNGh0dHA6Ly93d3cuc291bmRib3kuZGUAAAAAAAAAACU=");
    snd.play();
}

1 个答案:

答案 0 :(得分:1)

您以错误的方式使用setTimeout。例如,看看这部分:

setTimeout(function(){},4000);
speak("if details are correct ,please say yes else say no after beep");
setTimeout(function () { SoundMake(); }, 4000);
setTimeout(function() {startDictation(event);},3000);
setTimeout(function() { },4000);

看起来您希望执行在第一行停止4秒,然后继续执行第二行。但事实并非如此。唯一被延迟的是你作为参数传递给setTimeout的函数:它将在稍后调用。但引擎将立即继续下一个声明。实际上,在传递所有剩余代码之前,传递给setTimeout 的所有函数都不能执行。

所以......现在你可以看到上面这一块的第一行是没用的。它说:“从现在起4秒内不做任何事,现在继续下一个声明”

如何修复

有几种方式,有些是丑陋的,有些是好的,有些是介于两者之间的方式:

1。累计延迟时间

知道所有setTimeout次呼叫几乎同时执行,请指定一个延迟,该延迟也会计入之前的延迟:

setTimeout(function(){
    speak("if details are correct, please say yes else say no after beep");
},4000);
setTimeout(function () { SoundMake(); }, 4000+4000);
setTimeout(function() {startDictation(event);},4000+4000+3000);
setTimeout(function() { 
    // ...etc
},4000+4000+3000+4000);

缺点是:

  • 当你在一次延迟时改变主意时,你需要在几个地方进行调整。你可以通过使用一个变量来解决这个问题,你可以在下一个延迟时增加它。
  • 当其中一个计划的操作需要花费大量时间(或者浏览器忙于处理其他事情)时,操作之间的间隔可能会比预期的要小很多。

2。嵌套回调

在这里,您将下一个操作放在提供给setTimeout的前一个回调中:

setTimeout(function(){
    speak("if details are correct, please say yes else say no after beep");
    setTimeout(function () { 
        SoundMake();
        setTimeout(function() {
            startDictation(event);
            setTimeout(function() { 
                // ...etc
            }, 4000);
        }, 3000);
    }, 4000);
}, 4000);

缺点是:

  • 所谓的"callback hell":您的代码可以得到非常深层次的嵌套,在极端情况下,您的编辑器可能会显示大部分空白区域,只有向右滚动才会显示您的代码。这不实用。

3。递归

在这里你继续调用下一个计时器滴答时再次调用的相同函数:

(function loop(i) {
    var delay = 300;
    switch (i) {
    case 0:
        // Do nothing, just launch the setTimeout
        break;
    case 1:
        speak("if details are correct, please say yes else say no after beep");
        break;
    case 2: 
        SoundMake();
        delay = 300;
        break;
    case 3:
        startDictation(event);
        break;
    default:
        // etc...
        return; // start no more timeout
    }
    setTimeout(loop.bind(null, i+1), delay); 
})(0); // start with 0

缺点是:

  • switch声明非常详细。您也可以创建一个对象数组,其中每个对象都有作为函数属性执行的代码,以及作为另一个属性的延迟。然后你可以在loop正文中对其进行索引。

4。许

由于ES6有一个Promise对象,许多程序员会建议将其用于此目的,我自己包括:

// Utility to get a promise object that resolves after a given delay
function promiseDelay(delay) {
    return new Promise(function (resolve) {
        setTimeout(resolve, delay);
    });
}

promiseDelay(400)
.then(function() {
    speak("if details are correct ,please say yes else say no after beep");
    return promiseDelay(4000);
}).then(function () { 
    SoundMake();
    return promiseDelay(3000);
}).then(function () {
    startDictation(event);
    return promiseDelay(4000);
}).then(function () {
    // etc...
});

此代码非常干净且精益。

说明

请注意,上述内容只是代码的一部分。您在 Typer 函数中遇到了相同的问题。但原则是一样的。采取您的首选解决方案并将其应用到整个过程中。