Javascript 优化react代码以同时而不是按顺序加载来自多个源的数据

Javascript 优化react代码以同时而不是按顺序加载来自多个源的数据,javascript,reactjs,Javascript,Reactjs,我在页面上有两个选项卡,显示从不同数据源生成的可视化。这两种可视化都需要在后台进行多个查询,以便在呈现数据之前获取数据,因此每个选项卡单独加载都需要一些时间。当前,componentDidMount如下所示: componentDidMount(){ this.loadDataA(); this.loadDataB(); } 虽然它可以工作,但在A的数据加载完成之前,它不会开始加载B的数据。如果我颠倒组件didmount中的顺序,如下所示: componentDidMount(){

我在页面上有两个选项卡,显示从不同数据源生成的可视化。这两种可视化都需要在后台进行多个查询,以便在呈现数据之前获取数据,因此每个选项卡单独加载都需要一些时间。当前,
componentDidMount
如下所示:

componentDidMount(){
   this.loadDataA();
   this.loadDataB();
}
虽然它可以工作,但在A的数据加载完成之前,它不会开始加载B的数据。如果我颠倒
组件didmount
中的顺序,如下所示:

componentDidMount(){
   this.loadDataB();
   this.loadDataA();
}
this.loadDataA();
this.loadDataB();
然后它先加载B的数据,然后加载A的数据

有没有一种方法可以同时加载两个数据

(我还没有反应过来,所以如果我遗漏了什么,请告诉我)

编辑1 以下是加载数据功能:

async loadDataA(){
    const { queries } = this.state;
    queries.forEach((query) => {
      a_query({query}).then(result => this.handleAResult(result));
    });
  }

async loadDataB(){
    const { scopes, queries } = this.state;

     queries.forEach(query => {
       scopes.forEach(scope => {
        b_query({scope, query}).then(result => this.handleBResult(result));
     });
   });
 }
编辑2 添加
console.log
时的执行顺序(感谢@TKoL),首先调用A,然后调用B:


注意:如果您需要了解代码的任何其他部分,请询问。

您需要使用以下承诺使
loadDataA
loadDataB
异步:

下面是一个使用
async
语法糖的示例:

const loadDataA = async () => {
     // Actual load logic goes here
}

您需要使用以下承诺使
loadDataA
loadDataB
异步:

下面是一个使用
async
语法糖的示例:

const loadDataA = async () => {
     // Actual load logic goes here
}

到目前为止,阅读所有内容时,似乎
b_query
a_query
之后完成,反之亦然,具体取决于调用顺序。因此,要么它们具有导致排序的逻辑,要么服务器端本身对请求进行排序(是的,有一些功能可以做到这一点)

编辑1


第三种可能性是,无论您调用哪个端点,都会首先完成,因此响应会更快地发回,从而触发
。然后在第二次调用完成之前返回
(谢谢@TKoL).

到目前为止,阅读所有内容时,根据调用顺序,
b\u query
似乎在
a\u query
之后完成,反之亦然。因此,要么它们具有导致排序的逻辑,要么服务器端本身对请求进行排序(是的,有一些功能可以做到这一点)

编辑1


第三种可能性是,无论您调用的是哪个端点,都会首先完成,因此响应会更快地发回,从而触发
。然后在第二次调用完成之前(谢谢@TKoL)。

因此,您的加载代码:

async loadDataA(){
    const { queries } = this.state;
    queries.forEach((query) => {
      a_query({query}).then(result => this.handleAResult(result));
    });
  }

async loadDataB(){
    const { scopes, queries } = this.state;

     queries.forEach(query => {
       scopes.forEach(scope => {
        b_query({scope, query}).then(result => this.handleBResult(result));
     });
   });
 }
你这样称呼它:

componentDidMount(){
   this.loadDataB();
   this.loadDataA();
}
this.loadDataA();
this.loadDataB();
现在,我的理论是,它实际上工作得非常好。假设您的代码工作的方式是,它调用一个_查询_1,然后调用一个_查询_2,然后调用一个_查询…z,然后执行所有的b_查询,但不等待它返回a_查询的结果

因此,我建议添加以下console.log行以验证:

async loadDataA(){
    const { queries } = this.state;
    queries.forEach((query, index) => {
      console.log('starting queryA ' + index);
      a_query({query}).then(result => {
        console.log('finishing queryA ' + index);
        this.handleAResult(result)
      });
    });
  }

async loadDataB(){
    const { scopes, queries } = this.state;

     queries.forEach((query, qi) => {
       scopes.forEach((scope, si) => {
        console.log('starting queryB ' + qi + ':' + si);
        b_query({scope, query}).then(result => {
            console.log('finishing queryB ' + qi + ':' + si);
            this.handleBResult(result);
        });
     });
   });
 }

您应该首先看到所有的
开始
日志,A和B日志,然后您应该在日志开始完成时开始看到
完成
日志。这应该验证A和B是否“同时”运行,即B请求在B请求开始之前没有等待A请求完成。

因此,您有您的加载代码:

async loadDataA(){
    const { queries } = this.state;
    queries.forEach((query) => {
      a_query({query}).then(result => this.handleAResult(result));
    });
  }

async loadDataB(){
    const { scopes, queries } = this.state;

     queries.forEach(query => {
       scopes.forEach(scope => {
        b_query({scope, query}).then(result => this.handleBResult(result));
     });
   });
 }
你这样称呼它:

componentDidMount(){
   this.loadDataB();
   this.loadDataA();
}
this.loadDataA();
this.loadDataB();
现在,我的理论是,它实际上工作得非常好。假设您的代码工作的方式是,它调用一个_查询_1,然后调用一个_查询_2,然后调用一个_查询…z,然后执行所有的b_查询,但不等待它返回a_查询的结果

因此,我建议添加以下console.log行以验证:

async loadDataA(){
    const { queries } = this.state;
    queries.forEach((query, index) => {
      console.log('starting queryA ' + index);
      a_query({query}).then(result => {
        console.log('finishing queryA ' + index);
        this.handleAResult(result)
      });
    });
  }

async loadDataB(){
    const { scopes, queries } = this.state;

     queries.forEach((query, qi) => {
       scopes.forEach((scope, si) => {
        console.log('starting queryB ' + qi + ':' + si);
        b_query({scope, query}).then(result => {
            console.log('finishing queryB ' + qi + ':' + si);
            this.handleBResult(result);
        });
     });
   });
 }

您应该首先看到所有的
开始
日志,A和B日志,然后您应该在日志开始完成时开始看到
完成
日志。这应该验证A和B是否“同时”运行,即B请求没有在B请求开始之前等待A请求完成。

如果
loadDataA
loadDataB
都是异步加载数据,它们将按照您编写数据的方式同时加载数据。如果数据不是异步加载的,那么就没有办法同时加载。我想问题是,加载数据的来源和方式是什么?是的,数据是异步加载的。数据从不同的源加载,没有重叠。不过,根据函数的位置,它会按顺序执行。另外,我还注意到,如果在两个函数中都使用了
console.log
,那么它会立即打印它们。但是,在第一个函数完成之前,后面函数的数据加载不会开始。我在这里遗漏了什么吗?你怎么知道
B
数据请求直到
A
完成才开始?如果没有看到加载数据的特定代码,很难说如果
loadDataA
loadDataB
都是异步加载数据,那么它们就已经按照您编写数据的方式同时加载了。如果数据不是异步加载的,那么就没有办法同时加载。我想问题是,加载数据的来源和方式是什么?是的,数据是异步加载的。数据从不同的源加载,没有重叠。不过,根据函数的位置,它会按顺序执行。另外,我还注意到,如果在两个函数中都使用了
console.log
,那么它会立即打印它们。但是,在第一个函数完成之前,后面函数的数据加载不会开始。我在这里遗漏了什么吗?你怎么知道
B
数据请求直到
A
完成才开始?在没有看到加载数据的特定代码的情况下,很难说还有第三个选项您没有提到