使用es6promise顺序进行远程调用

use es6promise to make remote call sequentially

我正在尝试使用 es6 promise 依次进行两个远程调用, 这是我的代码

recordsCount(){
        let classInstance=this;
        let stateIns=this.state;
        return axios.post('/api/projectDocs/count',stateIns.gpSearch).then((response)=>{
            stateIns.totalRecords=response.data;
            classInstance.setState(stateIns);
        });

    }


loadGpDocs(start, end){
        let classInstance=this;
        let stateIns=this.state;
        stateIns.gpSearch.start=start;
        stateIns.gpSearch.end=end;
        return axios.post('/api/projectDocs/search',stateIns.gpSearch).then((response)=>{
            stateIns.data.gpDocs=response.data;
            classInstance.setState(stateIns);
        });
    }

调用这两个函数的代码

classInstance.recordsCount().then(classInstance.loadGpDocs(0, 20).then(function () {
                stateIns.ready = true;
                classInstance.setState(stateIns);
            }));

首先调用记录计数,这个 return 是一个 axios 承诺,然后加载数据,这个 return axios 承诺然后将更改应用到 UI。

我遗漏了一些东西,调用不按顺序,请帮助我理解承诺,为什么这段代码不按顺序?

下面会依次调用代码,这是因为我们使用的是promise chaining来实现"blocking"。由于所有返回的 promise 最初都以 pending 状态开始,因此每个 promise 都将被正确等待,并且直到前一个 promise 处于 fulfilled 状态时才会调用下一个 promise。

会按照以下顺序执行

  1. 调用 recordsCount() 并更新 stateIns.totalRecords
  2. 调用 loadGpDocs() 并更新 stateIns.data.gpDocs
  3. 更新stateIns.ready

    return classInstance.recordsCount()
      .then(() => {  // Wait for recordsCount() to be fulfilled
        // Notice that we are returning this promise
        // the next then() will wait until loadGpDocs is fulfilled
        return classInstance.loadGpDocs(0, 20);
      })
      .then(() => {
        stateIns.ready = true;
        classInstance.setState(stateIns);
      });
    

问题是 loadGpDocs(0, 20) 在承诺链 外部 被调用

你可以这样解决:

classInstance.recordsCount()
  .then(classInstance.loadGpDocs.bind(classInstace, 0, 20))
  .then(function () {
       stateIns.ready = true;
       classInstance.setState(stateIns);
   }));

请注意,classInstance.loadGpDocs.bind(classInstace, 0, 20) 返回一个 函数 并应用其参数 而不是调用它 ,因此它在每当 recordsCount() 承诺完成时承诺链