如何确定承诺结果的优先顺序?

时间:2018-06-15 15:51:31

标签: javascript reactjs asynchronous promise state

我正在研究一个反应应用程序。我需要使用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
            });
          }
        }

      });
}

3 个答案:

答案 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的回调中跟踪正在挂载/卸载的组件的状态,否则您可能会对未安装的组件执行操作。这也可能导致内存泄漏。