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
完成才开始?在没有看到加载数据的特定代码的情况下,很难说还有第三个选项您没有提到