【发布时间】:2020-04-09 04:59:24
【问题描述】:
我有一个 React 组件,它在 componentDidUpdate 中调用 async 函数。在该函数中,我有一个名为 Promise.all 的项目数组。在一种情况下,根据从先前的 axios 调用返回的内容进行 axios 调用。我遇到的问题是 axios 调用是在之前的 axios 调用的结果完成之前进行的,我不确定为什么会这样。
这是我的代码:
class Test extends Component {
this.state = {
experiments: []
}
async componentDidMount() {
await this.getExperiments(); // function to fetch experiments from a db
}
async componentDidUpdate() {
if (condition) {
await myFunction()
}
}
myFunction = async () => {
try {
const { experiments } = this.state;
const results = await Promise.all(experiments.map(async experiment => {
const firstAxiosCall = await axios.get(someUrl);
const secondAxiosCall = await axios.get(anotherUrl)
const { data } = secondAxiosCall; // THIS IS WHERE BUG OCCURS
if (data.length === 0) { // For one experiment, this is not empty, but it still goes into the if statement.
await axios.post(thirdUrl)
}
}));
} catch (e) {
console.log('ERROR', e);
}
}
}
我知道这是一个错误,因为调用了 if 语句中的 axios 调用,并且我在后端收到一个 db 错误,说没有传入任何内容。我希望来自第二个 axios 调用的数据首先返回在继续 if 语句之前。是不是我做错了什么?
我希望这是足够的信息!
谢谢大家!
【问题讨论】:
-
map()在进入下一个迭代之前不会等待承诺解决。我建议使用像bluebird这样的库来处理异步收集方法 -
你的代码写在那里的方式应该是
firstAxiosCall,然后是secondAxiosCall,然后是{data}行,然后是if。你正在等待一切正常。我怀疑您的问题与您描述的不同 -
试试
const { data } = await secondAxiosCall;。我不确定这是否可行,但尝试一下也无妨。 -
@MichaelOssig - 常规
for循环执行await(所有类型的for循环)。这是一个非常有用的功能。.forEach(),.map(),.filter()不要。但是,常规的for循环可以。 -
@MichaelOssig -
.map()中的 Bluebird 的并发功能仍然非常有用。但是,我发现我不再需要它了。我希望看到 Javascript 添加一些承诺感知数组迭代。现在有了 asyncIterators 的基础。
标签: javascript node.js reactjs api promise