我怎么能只有一个功能 运行 在另一个功能完成时才能使用? (for 循环中的 setTimeout)
How can I have one function run only when the other has finished ? (setTimeout within for-loop)
我正在尝试找到一种简单、直接的方法,以便在第一个函数完成后将第二个函数转至 运行。我已经尝试了一些我在网上遇到的建议,但由于它们在 for 循环中具有 setTimeouts,因此这些特定函数的运行方式似乎有所不同。到目前为止,我尝试过的所有操作都会导致第二个功能在第一个功能完成之前 运行(更新页面上的某些颜色样式)。
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>
您可以使用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);
}
}
您可以尝试这样的操作:
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
state 是一个包含 4 个元素的数组。
ShortestPath
state 是一个包含 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
,它将按您的预期工作。
我正在尝试找到一种简单、直接的方法,以便在第一个函数完成后将第二个函数转至 运行。我已经尝试了一些我在网上遇到的建议,但由于它们在 for 循环中具有 setTimeouts,因此这些特定函数的运行方式似乎有所不同。到目前为止,我尝试过的所有操作都会导致第二个功能在第一个功能完成之前 运行(更新页面上的某些颜色样式)。
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>
您可以使用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);
}
}
您可以尝试这样的操作:
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
state 是一个包含 4 个元素的数组。ShortestPath
state 是一个包含 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
,它将按您的预期工作。