简体   繁体   English

在遍历数组的 for 循环中执行递归 function 的最佳方法

[英]Best way to do a recursive function within a for loop iterating over an array

I have an array of letters:我有一系列字母:

const letters = ['a','b','c','d'];

I also have a function which takes a string argument letter and returns a concatenation of that letter and a random number.我还有一个 function,它接受一个字符串参数字母并返回该字母和一个随机数的串联。

function letterNumber(letter) {
   console.log(letter + '-' + Math.random());
}

What I am looking to do is to iterate over the letters array and for each item in the array to run the letterNumber function N times every X milliseconds, with the array item being passed to the letter function argument .我想要做的是迭代字母数组,并为数组中的每个项目每 X 毫秒运行letterNumber function N 次,并将数组项目传递给字母 function argument

What would be the best (and most performant) way to achieve this?实现这一目标的最佳(也是最高效)方法是什么? Thanks a lot!非常感谢!

EDIT编辑

I have now made it work by moving the let iterator=0;我现在通过移动let iterator=0;让它工作了within the nameless function in the code below.在下面代码中的无名 function 中。 Is there a better way of doing this if faced with a lot of values in the letters array?如果面对letters数组中的很多值,是否有更好的方法来做到这一点?

const letters = ['a','b','c','d'];
const interval = 1000;
const runCount = 5;

function letterNumber(letter) {
    console.log(letter+'_'+Math.random());
}

for (let i = 0;i<letters.length;i++) {   
    (function(i) {
        let iterator=0;
        let iter = setInterval(function() {
                if (iterator > runCount-1) {
                    clearInterval(iter);
                } else {
                    letterNumber(letters[i]);
                    iterator++;
                }
        }, interval)
    })(i);
}

EDIT - I apologize, I initially misunderstood your question.编辑 - 抱歉,我最初误解了你的问题。 Here's how I would recommend running through this.以下是我建议的运行方式。


It's been a while since I've worked with Javascript, so bear with me.自从我与 Javascript 合作以来已经有一段时间了,所以请耐心等待。 Instead of the setInterval() and clearInterval() combination, I would go with the setTimeout() function. I don't know the technical ins and outs of it, but much like the setInterval() function you provide the setTimeout() function two arguments - the function/command you wish to run, then how long you wish to wait.而不是setInterval()clearInterval()组合,我会 go 与setTimeout() function。我不知道它的技术细节,但很像setInterval() function 你提供setTimeout() function两个 arguments - 您希望运行的功能/命令,然后您希望等待多长时间。 This is how I would utilize this:这就是我将如何利用它:

let iterator = 1;

function letterNumber(letter) {
    console.log(`${letter}_${Math.ceil(Math.random() * 25) }`);
}

while (iterator <= runCount){
    setTimeout(() => letters.forEach(letterNumber), interval * iterator);
    iterator++;
}

You'll notice in the second argument passed into the setTimeout() function, I provided the value of the interval times the iterator.您会注意到在传递给setTimeout() function 的第二个参数中,我提供了时间间隔乘以迭代器的值。 The reason is that setTimeout() is executed as synchronous code, and the multiple calls to setTimeout() all run at the same time.原因是setTimeout()是作为同步代码执行的,并且对setTimeout()的多次调用都是同时运行的。 Each call to setTimeout() creates asynchronous code that will execute later, after the given delay.每次调用setTimeout()都会创建异步代码,这些代码将在给定的延迟后稍后执行。 Which is why the amount of the delay has to be produced dynamically.这就是为什么必须动态产生延迟量的原因。 Otherwise, if I were to use this code:否则,如果我要使用此代码:

while (iterator <= runCount){
    setTimeout(() => letters.forEach(letterNumber), interval);
    iterator++;
}

It would queue each call to the setTimeout() function, then each call will wait the specified amount (in this case, each call would be waiting for 1 second) then all run at the same time.它会将对setTimeout() function 的每个调用排队,然后每个调用将等待指定的时间(在这种情况下,每个调用将等待 1 秒),然后所有调用同时运行。

So when we run it with a dynamically created interval ( interval * iterator ), each call waits 1 second longer than the previous call to run, resulting in a delay between each return.因此,当我们使用动态创建的间隔( interval * iterator )运行它时,每次调用等待的时间比上一次运行的调用长 1 秒,导致每次返回之间有延迟。

I hope I explained that well enough, sorry if I may have missed out on some of the details, but this should provide you the results your looking for.我希望我解释得足够好,如果我可能错过了一些细节,我深表歉意,但这应该会为您提供您想要的结果。

Another thing to take note of, in the code I provided, I set the iterator to 1, and the condition for the while statement is testing for the iterator begin less than or equal to the runCount.另外需要注意的是,在我提供的代码中,我将迭代器设置为1,而while语句的条件是测试迭代器开始小于或等于runCount。 I started with 1, so that the first result of the setTimeout() function was delayed by one second.我从 1 开始,因此setTimeout() function 的第一个结果延迟了一秒。

If you wish to have the first result set returned immediately, you can change the initialization of the iterator variable to 0, and change the while condition to a plain less than statement like so:如果希望立即返回第一个结果集,可以将迭代器变量的初始化更改为 0,并将 while 条件更改为简单的小于语句,如下所示:

let iterator = 0;

...

while (iterator < runCount){
   ...
}

Another thing to look out for is what Math.random() does.另一件需要注意的事情是Math.random()的作用。 Currently, it provides you with a decimal value between 0 (inclusive) and 1 (exclusive).目前,它为您提供介于 0(含)和 1(不含)之间的十进制值。 In other words, possible values range from 0 to 0.99999 repeating.换句话说,可能的值范围从 0 到 0.99999 重复。 So if you want to get an integer value, you can do something like this:所以如果你想得到一个 integer 的值,你可以这样做:

function letterNumber(letter {
   console.log(letter + '-' + (Math.ceil(Math.random() * 25) )
}

The above code would provide you integer values from 1 to 25.上面的代码将为您提供从 1 到 25 的 integer 个值。

If you want more details, you can take a look at this MDN article on the Math.random() function.如果您想了解更多详细信息,可以查看有关 Math.random() function 的 MDN 文章。

I really hope this helps: :)我真的希望这会有所帮助::)

You could get rid of the closure and use a local scope for item/letter, iterator count and iter .您可以摆脱闭包并使用本地 scope 作为项目/字母、 iterator计数和iter

 function letterNumber(letter) { console.log(letter + '_' + Math.random()); } const letters = ['a', 'b', 'c', 'd'], interval = 1000, runCount = 5; for (const item of letters) { let iterator = 0, iter = setInterval(function() { if (++iterator > runCount) clearInterval(iter); else letterNumber(item); }, interval); }
 .as-console-wrapper { max-height: 100%;important: top; 0; }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM