【问题标题】:How can I slow down this for-loop and set state every 400 milliseconds?如何减慢这个 for 循环并每 400 毫秒设置一次状态?
【发布时间】:2020-06-05 17:01:54
【问题描述】:

我正在尝试在 React 中创建一个排序算法可视化工具。 此函数正在运行,但我想减慢 for 循环的速度,以便每 400 毫秒设置一次状态。

bubbleSort = (arr) => {
        console.log('bubblesort is running');
        var len = arr.length;
        console.log('array length: ', len);
        console.log(arr);

        for (var i = len-1; i>=0; i--){
                 console.log("i: ", i); 
                 for(var j = 1; j<=i; j++){
                     console.log("j: ", j);
                     if(arr[j-1]>arr[j]){
                        var temp = arr[j-1];
                        arr[j-1] = arr[j];
                        arr[j] = temp;
                        console.log("current array: ", arr);
                        this.setState({
                            array: arr
                        })
                     }
                 }
            } 
            console.log("final array: ", arr)
            return arr
     }

【问题讨论】:

  • 你不能,除非完全重写代码。 JavaScript(实际上)是单线程的,因此您必须将代码分成更小的单元,以便控制事件循环和其他可能想要显示该状态的代码。
  • 这能回答你的问题吗? Sleep in JavaScript - delay between actions
  • @Alnitak 现在可以了。 async/await 允许您在不重写的情况下执行此操作。现在写答案...
  • @Amadan 我希望这非常接近于完全重写,特别是因为在 OPs 代码中没有你可以await 的函数调用。
  • 您可以在标准的for 循环中使用await,这将“错开”循环的迭代。

标签: javascript reactjs for-loop bubble-sort


【解决方案1】:

最简单的方法是使用async/await范式。

创建一个实现延迟的函数(通过返回一个超时后解决的承诺):

const delay = (ms) => new Promise((resolve, reject) => setTimeout(resolve, ms));

然后将您的函数转换为async 函数:

bubbleSort = async (arr) => {

最后,将延迟调用添加到您的循环中:

await delay(400);

编辑:对于 cmets,使用 setTimeout 意味着函数不可能直接返回结果,因为在函数退出时结果将不可用。如果您只关心可视化排序,以上内容就足够了。如果您真的想要排序后的数组,则必须等待您的 bubbleSort 函数(或链接它返回的承诺):

// needs to be inside `async` function
let sortedArray = await bubbleSort(array);

// the result needs to be used in callback
bubbleSort(array).then(sortedArray => ... );

【讨论】:

  • 很公平,虽然这个函数的 caller 现在需要知道 await 才能得到结果,这意味着要么该函数必须是 async 要么使用直接的 Promise 以便它知道排序何时完成
  • @Alnitak 正确。不可能减慢 同步 函数。没有办法插入延迟并让函数仍然返回有意义的结果。无论您使用setTimeoutPromise 还是async/await 范式,这都是正确的。我想我应该在答案中注明...
  • async / await 可能是病毒式的——一旦你将它们添加到调用堆栈的某个位置,你往往不得不一直向上传播
猜你喜欢
  • 2016-06-19
  • 2015-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-17
  • 1970-01-01
  • 2020-06-29
相关资源
最近更新 更多