Javascript 为什么setTimeout不';我的冒泡排序功能(REACT)不起作用
我正在尝试可视化我的冒泡排序算法,所以我希望该算法等待50毫秒才能可视化。我尝试使用setTimeout和async函数,但它不起作用,当您删除setTimeout函数时,您可以看到数组已排序,而在函数中它就是不起作用。 该项目已安装bootstap@next和popper.jsJavascript 为什么setTimeout不';我的冒泡排序功能(REACT)不起作用,javascript,reactjs,asynchronous,Javascript,Reactjs,Asynchronous,我正在尝试可视化我的冒泡排序算法,所以我希望该算法等待50毫秒才能可视化。我尝试使用setTimeout和async函数,但它不起作用,当您删除setTimeout函数时,您可以看到数组已排序,而在函数中它就是不起作用。 该项目已安装bootstap@next和popper.js import React, { useEffect, useState, Fragment } from 'react'; import 'bootstrap/dist/css/bootstrap.css'; impo
import React, { useEffect, useState, Fragment } from 'react';
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap/dist/js/bootstrap.js';
import './App.css'
function App() {
const [values, setValues] = useState([43,4,3,56,6,3,36,56,7,5,45,34,87,99,34]);
const [render, setRender] = useState(false)
function forceRender() {
setRender(true)
}
useEffect(() => {
if(render) {
setRender(false)
}
}, [render])
function bubble(arr) {
for(let j = 0, len = arr.length; j < len; j++) {
for (let i = 0; i < len; i++) {
if (arr[i] > arr[i + 1]) {
setTimeout(()=>{
let temp = arr[i + 1];
arr[i + 1] = arr[i];
arr[i] = temp;
setValues(arr);
}, 50)
}
}
}
}
useEffect(() => {
bubble(values)
}, []);
useEffect(() => {
forceRender()
}, [values])
return (
<Fragment>
<nav className="navbar navbar-dark bg-dark">
<div className="container">
<span className="navbar-brand mb-0 h1">React Sorting</span>
</div>
</nav>
<div className="container sorting-container">
<div className="row">
<div className="sorting">
{
values.map(e => {
return (
<div className="bar" style={{height: `${e}%`}}>
<div className="bar-text">{e}</div>
</div>
)
})
}
</div>
</div>
</div>
</Fragment>
);
}
export default App;
import React,{useffect,useState,Fragment}来自'React';
导入'bootstrap/dist/css/bootstrap.css';
导入'bootstrap/dist/js/bootstrap.js';
导入“./App.css”
函数App(){
常量[值,设置值]=使用状态([43,4,3,56,6,3,36,56,7,5,45,34,87,99,34]);
const[render,setRender]=useState(false)
函数forceRender(){
setRender(真)
}
useffect(()=>{
如果(渲染){
setRender(错误)
}
},[render])
函数气泡(arr){
for(设j=0,len=arr.length;jarr[i+1]){
设置超时(()=>{
设温度=arr[i+1];
arr[i+1]=arr[i];
arr[i]=温度;
设定值(arr);
}, 50)
}
}
}
}
useffect(()=>{
气泡(值)
}, []);
useffect(()=>{
forceRender()
},[值])
返回(
反应分选
{
values.map(e=>{
返回(
{e}
)
})
}
);
}
导出默认应用程序;
您需要提示setTimeout
并使用asyc
和wait
来同步流程。
试试这个解决方案
import React, { useEffect, useState, Fragment } from 'react';
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap/dist/js/bootstrap.js';
import './App.css'
function App() {
const [values, setValues] = useState([43,4,3,56,6,3,36,56,7,5,45,34,87,99,34]);
const [render, setRender] = useState(false)
function forceRender() {
setRender(true)
}
useEffect(() => {
if(render) {
setRender(false)
}
}, [render])
function later(delay) {
return new Promise(function(resolve) {
setTimeout(resolve, delay);
});
}
async function bubble(arr) {
for(let j = 0, len = arr.length; j < len; j++) {
for (let i = 0; i < len; i++) {
if (arr[i] > arr[i + 1]) {
await later(50);
let temp = arr[i + 1];
arr[i + 1] = arr[i];
arr[i] = temp;
setValues(arr);
}
}
}
}
useEffect(() => {
bubble(values)
}, []);
useEffect(() => {
forceRender()
}, [values])
return (
<Fragment>
<nav className="navbar navbar-dark bg-dark">
<div className="container">
<span className="navbar-brand mb-0 h1">React Sorting</span>
</div>
</nav>
<div className="container sorting-container">
<div className="row">
<div className="sorting">
{
values.map(e => {
return (
<div className="bar" style={{height: `${e}%`}}>
<div className="bar-text">{e}</div>
</div>
)
})
}
</div>
</div>
</div>
</Fragment>
);
}
export default App;
从“React”导入React,{useffect,useState,Fragment};
导入'bootstrap/dist/css/bootstrap.css';
导入'bootstrap/dist/js/bootstrap.js';
导入“./App.css”
函数App(){
常量[值,设置值]=使用状态([43,4,3,56,6,3,36,56,7,5,45,34,87,99,34]);
const[render,setRender]=useState(false)
函数forceRender(){
setRender(真)
}
useffect(()=>{
如果(渲染){
setRender(错误)
}
},[render])
功能稍后(延迟){
返回新承诺(函数(解析){
设置超时(解析、延迟);
});
}
异步函数气泡(arr){
for(设j=0,len=arr.length;jarr[i+1]){
待会儿(50);
设温度=arr[i+1];
arr[i+1]=arr[i];
arr[i]=温度;
设定值(arr);
}
}
}
}
useffect(()=>{
气泡(值)
}, []);
useffect(()=>{
forceRender()
},[值])
返回(
反应分选
{
values.map(e=>{
返回(
{e}
)
})
}
);
}
导出默认应用程序;
setTimeout()是一个非阻塞函数,也就是说,它不会停止程序,直到它从超时返回。
程序中发生的情况是,第一次迭代要求setTimeout在50毫秒后进行交换,然后立即跳转到下一次迭代,下一次迭代也会这样做,所有的迭代都设置为50毫秒后运行,但彼此之间的间隔不是50毫秒
除了Prime的解决方案之外,您还可以使用一个变量,比如说t=50
,在if
语句中,该变量每次迭代增加50,然后将该变量的值t
传递给setTimeout,通过这种方式,您将确保每个迭代将运行其元素交换,彼此之间的间隔至少为50毫秒
例如,请适应您的代码:
let t = 50;
function bubble(arr) {
for(let j = 0, len = arr.length; j < len; j++) {
for (let i = 0; i < len; i++) {
if (arr[i] > arr[i + 1]) {
setTimeout(()=>{
let temp = arr[i + 1];
arr[i + 1] = arr[i];
arr[i] = temp;
setValues(arr);
}, t)
t = t + 50;
}
}
}
}
设t=50;
函数气泡(arr){
for(设j=0,len=arr.length;jarr[i+1]){
设置超时(()=>{
设温度=arr[i+1];
arr[i+1]=arr[i];
arr[i]=温度;
设定值(arr);
},t)
t=t+50;
}
}
}
}
这段代码有很多问题阻碍了它的工作。举几个例子:
函数不是必需的,也不起作用forceRender()
违反了一些规则。该函数同时依赖于useffect
和bubble()
——任何带有类似于ESLint的linter的优秀IDE都会指出这个问题并帮助指导您。作为一种快速的解决方法,为了简单起见,我刚刚将值
和挂载时初始数组的设置一起移到了内部,以避免需要获取bubble()
值的当前状态
对于
中的bubble()
循环,所有
回调都指向相同的inssetTimeout