【问题标题】:Using a delay function inside another function in JavaScript在 JavaScript 的另一个函数中使用延迟函数
【发布时间】:2016-07-21 18:46:35
【问题描述】:

我是 JavaScript 新手,我有一个问题,代码如下所示:

function job1() {
    var subText1="";
    var subText2="";
    var text="";
    var vocabulary = "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz0123456789";

    // Use the delay function to create a full text in 20 * 150 milliseconds
    var i = 0, 
    action = function() {
                var temp = vocabulary.charAt(Math.floor(Math.random() * vocabulary.length));
                text+= temp;
                document.write(text + "<br>");
                i++;
                if (i < 20) {
                            setTimeout(action, 150);
                } else {
                    // The first subText is from position 0 until some random number random between 0 and the text length
                    subText1 = text.slice(0, Math.floor(Math.random() * text.length));
                    // The second subText is from where the first subText ends until the last character form the text input
                    subText2 = text.slice(subText1.length, text.length);

                    // output of the subText1 and the subText2 for the first time
                    document.write("subText1: " + subText1 + "<br>");
                    document.write("subText2: " + subText2 + "<br>");
                    document.write("text: " + text + "<br>");
                }
            };

        setTimeout(action, 0);

        // output of the subText1 and the subText2 once more
        document.write("subText1: " + subText1 + "<br>");
        document.write("subText2: " + subText2 + "<br>");

        // NextJob: job2, job3
        // job dependency
        var nextJob = "job2, job3";
        var prevJob = "null";

        // results
        return { 
        subText1_RT : subText1,
        subText2_RT : subText2
        };
}

我的问题是我需要将subText1 和subText2 从action = function().... 部分获取到此部分:

return { 
   subText1_RT : subText1,
   subText2_RT : subText2
};

但是subText1 和subText2 变量是空的。

代码如下:http://jsfiddle.net/TalGoz/4tgc372e/

看起来job1() 函数的所有部分都在action = function() 部分之前执行。让它像这样作为函数内部的函数工作是非常重要的,我不能为了我的目标而分离这些函数。

希望这里有人能帮我看看问题并解决它。

【问题讨论】:

  • setTimeout和return,一起用没意义。
  • @epascarello 为什么?我在这里使用它没有看到任何问题。如果使用正确,document.write 没有任何问题。问题是滥用,而不是不使用。
  • OP 正在运行 setTimeout 和 document.write,它将替换页面内容。在这里使用不当,99% 的情况下使用是错误的。
  • @epascarello document.write 只是为了查看输出。
  • 您不能从异步方法返回。完成后,您需要使用回调来执行最后的步骤。

标签: javascript jquery


【解决方案1】:

编辑:由于 JavaScript 的工作方式,文本值的最终处理需要在回调函数中进行——它是单线程的,意味着一次只运行一段代码。查看您的原始代码,执行首先进入job1()。它将action() 构建为一个函数而不执行它,然后它们继续执行setTimeout(),它将action() 设置为运行但尚未运行。要让 setTimeout() 实际执行,即使时间值为 0,当前代码也必须完成执行。接下来它移动到job1() 中的结束代码,即document.Write、job1/job3,并返回对象。由于action()还没有执行,subText对象还没有设置。

一旦控制离开job1(),并完成所有当前代码,浏览器将从您的setTimeout() 调用开始执行action()。在action() 内部还有其他 setTimeout 调用,它们的行为类似——当前代码必须完成执行,然后等待,最后指定的代码将执行。

因此,总而言之,您必须使用回调函数,因为执行必须在所有当前代码完成之后,任何使用 setTimeout() 排队的代码才会执行​​。您不能采用像 job1() 这样的异步函数并使其同步,因为当您在 job1() 内部时,任何异步 setTimeout() 调用都无法执行。

在某些其他语言中,例如 C++ 或 Java,您可以让代码并行运行,因此您可以在“后台线程”中生成代码,然后当前线程可以等待它完成,从而获得您想要的效果.你不能用 JavaScript 做到这一点。所有异步函数都需要回调。 Callback 的字面意思是“完成后给我回电话”。未来会有 Web Workers 支持同时运行多段代码:Web Workers

这是一个使用回调whendone 的示例,下面会引用它。设置值后调用它。

function job1(whendone) {
    var subText1="";
    var subText2="";
    var text="";
    var vocabulary = "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz0123456789";

    // Use the delay function to create a full text in 20 * 150 milliseconds
    var i = 0, 
    action = function() {
            var temp = vocabulary.charAt(Math.floor(Math.random() * vocabulary.length));
            text+= temp;
            document.write(text + "<br>");
            i++;
            if (i < 20) {
                        setTimeout(action, 150);
            } else {
                // The first subText is from position 0 until some random number random between 0 and the text length
                subText1 = text.slice(0, Math.floor(Math.random() * text.length));
                // The second subText is from where the first subText ends until the last character form the text input
                subText2 = text.slice(subText1.length, text.length);

                // output of the subText1 and the subText2 for the first time
                document.write("subText1: " + subText1 + "<br>");
                document.write("subText2: " + subText2 + "<br>");
                document.write("text: " + text + "<br>");

                // Now we're done
                whendone(subText1, subText2);
            }
        };

    setTimeout(action, 0);
}

job1(function(subText1, subText2) {
    // output of the subText1 and the subText2 once more
    document.write("subText1: " + subText1 + "<br>");
    document.write("subText2: " + subText2 + "<br>");

    // NextJob: job2, job3
    // job dependency
    var nextJob = "job2, job3";
    var prevJob = "null";

    // results
    var returned = { 
        subText1_RT : subText1,
        subText2_RT : subText2
    };

    // Your code doing something with 'returned' here
});

您想要的值以returned 结尾。如果你想对这个值做一些事情,在returned = 语句之后添加代码。

【讨论】:

  • 感谢这段代码!!!,是否有可能将整个事情封装在一个函数中,比如说function job(){...},它的最后会有输出参数。这个解决方案的问题是,最后我有两个相互交互的独立函数。我实际上需要一个我可以调用的function job(){...},并且这个函数可以在里面有其他函数,就像你在你的例子中那样,但最后只能通过调用job()函数(它包含所有其他函数)我想得到结果。再次感谢您的代码!
  • @TalG,没有任何方法可以拥有单一功能。我将编辑我的答案以进一步解释原因。
  • 感谢您的解释:)
猜你喜欢
  • 2016-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-01
  • 1970-01-01
相关资源
最近更新 更多