如何等待 3 个异步函数完成反应?
How to wait for 3 async functions to finish in react?
我正在使用以下库生成 sha256 哈希值:
https://www.npmjs.com/package/crypto-hash
哈希正在运行,但它是异步的。我想弄清楚如何等待以下代码执行:
async function hashAnswers() {
try {
await sha256(firstAnswer)
.then(hash => { setFirstHash(hash)})
await sha256(secondAnswer)
.then(hash => { setSecondHash(hash)})
await sha256(thirdAnswer)
.then(hash => { setThirdHash(hash)})
}
catch (error) {
console.log(error);
}
}
并在这里调用它:
async function handleSubmit() {
await hashAnswers().then(result => {
console.log(firstHash);
})
}
但是,它不会在记录之前等待散列的答案。
提前致谢
如果您使用 then
,则无需 await
。我不确定 setFirstHash
、setSecondHash
return 是什么,但看起来 Promise.all
可能会按照 Brian 的建议为您完成这项工作。这是要点:
const hashAnswers = () => {
const promises = [];
try {
promises.push(
sha256(firstAnswer).then(hash => {
setFirstHash(hash);
return 'first is set';
})
);
promises.push(
sha256(secondAnswer).then(hash => {
setSecondHash(hash);
return 'second is set'
})
);
/*
... More push() calls ...
*/
return promises;
}
catch (error) {
console.log(error);
return [];
}
}
const handleSubmit = () => {
Promise.all(hashAnswers())
.then(result => {
console.log(result);
})
}
请注意,如果出现错误,hashAnswers
return 是一个空数组,以便 Promise.all
可以解析,但您将通过 [=18= 看到错误消息]
编辑:
评论中提出的解决方案使用Promise.all
其实是一个很好的建议。你只需要让你的 hashAnswers
函数 return 一个值的元组,这些值是答案的散列:
async function hashAnswers() {
return Promise.all([
sha256(firstAnswer), sha256(secondAnswer), sha256(thirdAnswer),
]).catch(error => {
console.log(error);
return [null, null, null];
});
}
现在您的 handleSubmit
函数将可以访问值 returned:
async function handleSubmit() {
const [hash1, hash2, hash3] = await hashAnswers();
setFirstHash(hash1);
setSecondHash(hash2);
setThirdHash(hash3);
console.log(hash1);
}
上一个回答:
第一个问题是在react中,setState
是异步的,不会立即更新状态。因此,您对 setXHash
等的所有调用可能不会在您准备好使用它们之前实际更新状态。
第二个问题是您的函数将无法访问更新的值,因为它们将在组件的不同渲染中更新,这将不同于调用函数的当前渲染。请记住,每次状态更改都会导致整个组件 re-render.
解决方案?
有两种可能的解决方案:
- 创建另一个在函数完成时更新的状态
- 将哈希存储在可变引用中 (
useRef
)
第二个选项可能最容易实施:
const firstHashRef = useRef();
// Do the same for secondHashRef, etc
...
async function hashAnswers() {
try {
await sha256(firstAnswer)
.then(hash => { firstHashRef.current = hash; })
await sha256(secondAnswer)
.then(hash => { secondHashRef.current = hash; })
await sha256(thirdAnswer)
.then(hash => { thirdHashRef.current = hash; })
}
catch (error) {
console.log(error);
}
}
现在在您的 handleSubmit
函数中,您可以在异步 hashAnswers
完成后 console.log(firstHashRef.current)
。
我正在使用以下库生成 sha256 哈希值:
https://www.npmjs.com/package/crypto-hash
哈希正在运行,但它是异步的。我想弄清楚如何等待以下代码执行:
async function hashAnswers() {
try {
await sha256(firstAnswer)
.then(hash => { setFirstHash(hash)})
await sha256(secondAnswer)
.then(hash => { setSecondHash(hash)})
await sha256(thirdAnswer)
.then(hash => { setThirdHash(hash)})
}
catch (error) {
console.log(error);
}
}
并在这里调用它:
async function handleSubmit() {
await hashAnswers().then(result => {
console.log(firstHash);
})
}
但是,它不会在记录之前等待散列的答案。
提前致谢
如果您使用 then
,则无需 await
。我不确定 setFirstHash
、setSecondHash
return 是什么,但看起来 Promise.all
可能会按照 Brian 的建议为您完成这项工作。这是要点:
const hashAnswers = () => {
const promises = [];
try {
promises.push(
sha256(firstAnswer).then(hash => {
setFirstHash(hash);
return 'first is set';
})
);
promises.push(
sha256(secondAnswer).then(hash => {
setSecondHash(hash);
return 'second is set'
})
);
/*
... More push() calls ...
*/
return promises;
}
catch (error) {
console.log(error);
return [];
}
}
const handleSubmit = () => {
Promise.all(hashAnswers())
.then(result => {
console.log(result);
})
}
请注意,如果出现错误,hashAnswers
return 是一个空数组,以便 Promise.all
可以解析,但您将通过 [=18= 看到错误消息]
编辑:
评论中提出的解决方案使用Promise.all
其实是一个很好的建议。你只需要让你的 hashAnswers
函数 return 一个值的元组,这些值是答案的散列:
async function hashAnswers() {
return Promise.all([
sha256(firstAnswer), sha256(secondAnswer), sha256(thirdAnswer),
]).catch(error => {
console.log(error);
return [null, null, null];
});
}
现在您的 handleSubmit
函数将可以访问值 returned:
async function handleSubmit() {
const [hash1, hash2, hash3] = await hashAnswers();
setFirstHash(hash1);
setSecondHash(hash2);
setThirdHash(hash3);
console.log(hash1);
}
上一个回答:
第一个问题是在react中,setState
是异步的,不会立即更新状态。因此,您对 setXHash
等的所有调用可能不会在您准备好使用它们之前实际更新状态。
第二个问题是您的函数将无法访问更新的值,因为它们将在组件的不同渲染中更新,这将不同于调用函数的当前渲染。请记住,每次状态更改都会导致整个组件 re-render.
解决方案?
有两种可能的解决方案:
- 创建另一个在函数完成时更新的状态
- 将哈希存储在可变引用中 (
useRef
)
第二个选项可能最容易实施:
const firstHashRef = useRef();
// Do the same for secondHashRef, etc
...
async function hashAnswers() {
try {
await sha256(firstAnswer)
.then(hash => { firstHashRef.current = hash; })
await sha256(secondAnswer)
.then(hash => { secondHashRef.current = hash; })
await sha256(thirdAnswer)
.then(hash => { thirdHashRef.current = hash; })
}
catch (error) {
console.log(error);
}
}
现在在您的 handleSubmit
函数中,您可以在异步 hashAnswers
完成后 console.log(firstHashRef.current)
。