我试图找到一种简单、直接的方法,让第二个函数在第一个函数完成后运行。我尝试了一些我在网上遇到的建议,但这些特定函数的操作似乎有所不同,因为它们在for循环中设置了Timeouts。到目前为止,我所尝试的一切都会导致第二个函数在第一个函数完成之前运行(即更新页面上的一些颜色样式(。
const [VisitedNodes, setVisitedNodes] = useState([]);
const [ShortestPath, setShortestPath] = useState([]);
// runs first
function drawVisitedNodes() {
for (let i = 0; i < VisitedNodes.length; i++) {
const node = VisitedNodes[i];
setTimeout(() => {
document.getElementById(`${node.x}-${node.y}`).className =
"node-visited";
}, i);
}
drawShortestPath();
}
// runs second
function drawShortestPath() {
for (let i = 0; i < ShortestPath.length; i++) {
const node = ShortestPath[i];
setTimeout(() => {
document.getElementById(`${node.x}-${node.y}`).className =
"node-shortPath";
}, i * 10);
}
}
<button
onClick={drawVisitedNodes}>Visualize
</button>
您可以尝试以下操作:
const [VisitedNodes, setVisitedNodes] = useState([]);
const [ShortestPath, setShortestPath] = useState([]);
// runs first
function drawVisitedNodes() {
let x= 0;
for (let i = 0; i < VisitedNodes.length; i++) {
const node = VisitedNodes[i];
setTimeout(() => {
document.getElementById(`${node.x}-${node.y}`).className =
"node-visited";
}, i);
x++;
}
setTimeout(() => drawShortestPath(), x);
}
// runs second
function drawShortestPath() {
for (let i = 0; i < ShortestPath.length; i++) {
const node = ShortestPath[i];
setTimeout(() => {
document.getElementById(`${node.x}-${node.y}`).className =
"node-shortPath";
}, i * 10);
}
}
<button
onClick={drawVisitedNodes}>Visualize
</button>
这将给第二个函数的执行增加一些延迟。多少时间?x
会告诉你,因为在for
的末尾,它将是VisitedNodes.length
。是的,你也可以这样做:
setTimeout(() => drawShortestPath(), VisitedNodes.length)
所以,为了让你知道为什么这是有效的,我给你举下一个例子:
VisitedNodes
状态是一个由4个元素组成的数组- CCD_ 5状态是一个由2个元素组成的数组
- 单击该按钮将执行
drawVisitedNodes()
功能
在您的情况下,执行将是:
setTimeout(() => codeForNode1, 0)
setTimeout(() => codeForNode2, 1)
setTimeout(() => codeForNode3, 2)
setTimeout(() => codeForNode4, 3)
drawShortestPath()
但是,由于setTimeout的原因,实际执行将是:
drawShortestPath()
codeForNode1
codeForNode2
codeForNode3
codeForNode4
根据我的建议,您的代码将保持秩序。让我们看看:
setTimeout(() => codeForNode1, 0)
setTimeout(() => codeForNode2, 1)
setTimeout(() => codeForNode3, 2)
setTimeout(() => codeForNode4, 3)
setTimeout(() => drawShortestPath(), 4)
最终执行将是:
codeForNode1
codeForNode2
codeForNode3
codeForNode4
drawShortestPath()
在评论中,您问我为什么使用实际数字不起作用。好吧,我的答案是,这取决于你有多少VisitedNodes
。使用我刚才给你的例子,如果你使用x < 4
,它不会起作用,因为你试图在执行codeForNode4
之前执行drawShortestPath()
函数,所以在这种情况下你混合了执行。但是,如果您设置x ≥ 4
,它将按您的预期工作。
您可以使用await
等待所有逻辑完成
像这样
async function foo() {
for (let i = 0; i < VisitedNodes.length; i++) {
const node = VisitedNodes[i];
setTimeout(() => {
document.getElementById(`${node.x}-${node.y}`).className =
"node-visited";
}, i);
}
}
function drawVisitedNodes() {
await foo();
drawShortestPath();
}
// runs second
function drawShortestPath() {
for (let i = 0; i < ShortestPath.length; i++) {
const node = ShortestPath[i];
setTimeout(() => {
document.getElementById(`${node.x}-${node.y}`).className =
"node-shortPath";
}, i * 10);
}
}