假设我们有一个可观察的主对象数组,以及有关该数组的可观察数据(例如,假设我们有selectedReports
和reportParameters
)。现在,假设我们发出动作以将report
添加到数组或从该数组中删除report
。我们该如何执行动作以获取reportParameters
的数据,作为反应?
到目前为止,我的尝试无效,看起来像这样:
// report parameters stuff
async fetchAllReportParameters() {
reaction(
() => this.selectedReports,
async (reports) => {
// reset the report parameters
this.reportParameters = {}
// fetch the parameters for all the reports
await reports
.forEach((report) => {
this.fetchReportParameters(report.Id)
})
}
)
}
/**
* fetches report parameters for a reportId
* @param {number} reportId
*/
fetchReportParameters = (reportId) => {
this.reportParameters[reportId] = []
const onSuccess = (reportParameters) => {
this.reportParameters[reportId] = reportParameters
}
this.api.GetReportParameters(reportId)
.then(onSuccess, this.fetchReportParametersError)
}
fetchReportParametersError = (error) => {
// TODO: output some error here
}
答案 0 :(得分:1)
您真的打电话过fetchAllReportParameters
吗?如果您不这样做,将永远不会创建反应。相反,您可能想从构造函数创建reaction
,假设您始终希望运行它。一个例子:
class SomeStore {
constructor() {
this.disposeReportsReaction = reaction(
() => this.selectedReports.slice(),
reports => {
// ...
}
)
}
}
反应完成后,请致电storeInstanceName.disposeReaction()
。
请注意,我在这里使用了.slice()
。这是因为,如果仅传递数组引用,则永远不会调用该反应。请参见reaction
docs:您必须以某种方式实际使用该值。
您还需要稍微调整一下异步代码。这个:
async (reports) => {
await reports.forEach((report) => {
// ...
})
}
不会做您希望的事情,因为forEach
返回undefined
。即使将async
关键字移至forEach
回调,所有API请求也将快速连续发送。考虑使用类似的方法,具体取决于您是否要在发送下一个请求之前等待上一个请求:
try {
for (const report of reports) {
await this.fetchReportParameters(report.id)
}
} catch (e) {
// handle error
}
这并不总是正确的答案:有时可以快速连续发送一堆请求(也许特别是如果是一小批,和/或在HTTP / 2的情况下)。如果可以的话,您可以使用:
reports => {
// ...
reports.forEach(report => this.fetchReportParameters(report.id))
}