我正在研究一个反应应用程序。我需要使用api request的结果更新状态。现在应用程序的功能使我必须经常发出api请求。因此,一旦结果到达,我将在then()中设置状态。但有些结果比其他结果需要更多时间。因此,有时前一个承诺的结果会设置状态而不是当前状态。如何确定承诺的优先级,以便最新的请求结果设置状态。或者,一旦我打电话给新的承诺,还有另一种方法可以摆脱以前的承诺吗?
this.state = {
searchterm: '',
isfocused: false,
current: -1,
noresults: false,
// latest promise id
reqseqid: 0,
filteredList: []
}
callingfunction(){
let reqseqid = this.state.reqseqid + 1;
this.setState({
searchterm,
filteredList: [],
reqseqid
});
searchresults(searchterm, reqseqid)
.then(res => {
let { results, reqseqid } = res;
console.log(reqseqid, this.state.reqseqid);
if(reqseqid === this.state.reqseqid){
if(res.length === 0){
this.setState({
current: -1,
filteredList: [],
noresults: true
});
}else{
this.setState({
current: -1,
filteredList: results,
noresults: false
});
}
}
});
}
答案 0 :(得分:1)
我通常处理这个问题的方法是使用一个实例属性或类似的变量,异步回调可以检查它是否仍然需要它的结果或者请求是否过时。例如,在构造函数中:
this.ajaxSequence = 0;
然后提出您的请求:
const thisSequence = ++this.ajaxSequence;
doTheAjaxRequest()
.then(result => {
if (thisSequence == this.ajaxSequence) {
// Use the result
}
})
.catch(/*...probably check and ignore the error if this request was stale...*/);
它不一定是一个数字。例如:
this.currentRequestPromise = null;
然后
const thisPromise = this.currentRequestPromise = doTheAjaxRequest()
.then(result => {
if (thisPromise == this.currentRequestPromise) {
// Use the result
}
})
.catch(/*...probably check here too...*/);
答案 1 :(得分:0)
有很多方法可以做到这一点。我喜欢的一种方法是拥有一个跟踪收到的请求的对象实例(一个requestSequence
种类)以及每个请求的递增索引值。当请求/保证返回时,检查该请求索引的索引是否是> =您已从largestIndex
返回的requestSequence
。如果是,则返回该结果,并递增largestIndex
。否则,请不要返回该值。
此方法的好处是此代码的调用者可以根据需要快速发出请求,requestSequence
将确保订单。调用者不必关心过期请求或检查返回的值是否与当前输入匹配。
答案 2 :(得分:-1)
您应该查看执行流程的observable。您正在寻找的是非并行承诺承诺,这可以通过xstream
等库轻松完成:
const xs = require("xstream").default;
const promise$ = ... // create a stream of promises
return promise$.map(p => xs.fromPromise(p)).flatten();
创建承诺流很容易,假设您需要定期获取
const promise$ = xs.periodic(500).map(() => makeApiCall());
我强烈建议你朝这个方向看。尝试直接处理组件生命周期中的承诺并不简单,应该可以在Redux中间件(或其他状态管理实用程序)中完成。例如,它要求您在promise的回调中跟踪正在挂载/卸载的组件的状态,否则您可能会对未安装的组件执行操作。这也可能导致内存泄漏。