Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 同时执行两个功能_Javascript - Fatal编程技术网

Javascript 同时执行两个功能

Javascript 同时执行两个功能,javascript,Javascript,我有一个函数,在调用该函数时刷新组件的数据。此时,它一次只对一个组件起作用。但我想同时刷新两个组件。这是我的刷新功能: fetchDataByName = name => { const { retrievedData } = this.state; const { fetcher } = this.props; const fetch = _.find(fetcher, { name }); if (typeof f

我有一个函数,在调用该函数时刷新组件的数据。此时,它一次只对一个组件起作用。但我想同时刷新两个组件。这是我的刷新功能:

   fetchDataByName = name => {
        const { retrievedData } = this.state;
        const { fetcher } = this.props;
        const fetch = _.find(fetcher, { name });

        if (typeof fetch === "undefined") {
          throw new Error(`Fetch with ${name} cannot be found in fetcher`);
        }

        this.fetchData(fetch, (error, data) => {
          retrievedData[name] = data;
          this._isMounted && this.setState({ retrievedData });
        });
      };
fetchData = (fetch, callback) => {
    const { componentProps } = this.props;
    let { route, params = [] } = fetch;
    let fetchData = true;

    // if fetcher url contains params and the param can be found
    // in the component props, they should be replaced.
    _.each(params, param => {
      if (componentProps[param]) {
        route = route.replace(`:${param}`, componentProps[param]);
      } else {
        fetchData = false; // don't fetch data for this entry as the params are not given
      }
    });

    if (fetchData) {
      axios
        .get(route)
        .then(({ data }) => {
          if (this.isMounted) {
            callback(null, data);
          }
        })
        .catch(error => {
          if (error.response.status == 403) {
            this._isMounted && this.setState({ errorCode: 403 });
            setMessage({
              text: "Unauthorized",
              type: "error"
            });
          }

          if (error.response.status == 401) {
            this._isMounted && this.setState({ errorCode: 401 });
            window.location.href = "/login";
          }

          if (error.response.status != 403) {
            console.error("Your backend is failing.", error);
          }
          callback(error, null);
        });
    } else {
      callback(null, null);
    }
  };
我的函数调用如下:

refresh("meetingTypes");
const args = ['meetingTypes', 'exampleMeetingTypes'];
refresh(args);
当它作为道具传递到我的组件时:

return (
        <Component
          {...retrievedData}
          {...componentProps}
          refresh={this.fetchDataByName}
        />
      );
然后,如果
name
是一个数组,请检查my
fetchDataByName
函数,并在数组中循环以获取数据。但是,该函数仍然是一个接一个地执行,而不是同时执行。所以我的问题是:

实现这一目标的最佳方式是什么 函数立即执行,而不是第一次刷新MeetingType 然后举例说明会议类型

我应该使用
async/await
还是有更好的选择

fetchData
功能:

   fetchDataByName = name => {
        const { retrievedData } = this.state;
        const { fetcher } = this.props;
        const fetch = _.find(fetcher, { name });

        if (typeof fetch === "undefined") {
          throw new Error(`Fetch with ${name} cannot be found in fetcher`);
        }

        this.fetchData(fetch, (error, data) => {
          retrievedData[name] = data;
          this._isMounted && this.setState({ retrievedData });
        });
      };
fetchData = (fetch, callback) => {
    const { componentProps } = this.props;
    let { route, params = [] } = fetch;
    let fetchData = true;

    // if fetcher url contains params and the param can be found
    // in the component props, they should be replaced.
    _.each(params, param => {
      if (componentProps[param]) {
        route = route.replace(`:${param}`, componentProps[param]);
      } else {
        fetchData = false; // don't fetch data for this entry as the params are not given
      }
    });

    if (fetchData) {
      axios
        .get(route)
        .then(({ data }) => {
          if (this.isMounted) {
            callback(null, data);
          }
        })
        .catch(error => {
          if (error.response.status == 403) {
            this._isMounted && this.setState({ errorCode: 403 });
            setMessage({
              text: "Unauthorized",
              type: "error"
            });
          }

          if (error.response.status == 401) {
            this._isMounted && this.setState({ errorCode: 401 });
            window.location.href = "/login";
          }

          if (error.response.status != 403) {
            console.error("Your backend is failing.", error);
          }
          callback(error, null);
        });
    } else {
      callback(null, null);
    }
  };

我假设
fetchData
是异步工作的(ajax或类似)。要并行刷新数据的两个方面,只需进行两次调用,而不是一次调用:

refresh("meetingTypes");
refresh("exampleMeetingTypes");
两个ajax调用或其他调用将并行运行,每个调用完成后都会更新组件但是:请参见下面的“旁注”
fetchDataByName
有问题

如果要避免两次更新组件,则必须更新
fetchDataByName
以接受多个名称或返回结果承诺(或类似内容),而不是直接更新组件,这样调用者可以执行多个调用,并在执行更新之前等待两个结果


旁注:
fetchDataByName
的这一方面看起来可疑:

fetchDataByName = name => {
  const { retrievedData } = this.state;  // <=============================
  const { fetcher } = this.props;
  const fetch = _.find(fetcher, { name });

  if (typeof fetch === "undefined") {
    throw new Error(`Fetch with ${name} cannot be found in fetcher`);
  }

  this.fetchData(fetch, (error, data) => {
    retrievedData[name] = data;          // <=============================
    this._isMounted && this.setState({ retrievedData });
  });
};

通过使用
setState

的回调版本来异步执行操作,从而删除具有扩展的对象的就地突变,并使用最新版本的
retrievedData
,您可以使用
async/await
Promise
@PrerakSola-上面的
fetchData
很可能是异步的(旧式异步,使用回调)。本质上,调用异步函数无论如何都不会阻塞,。使用提供的代码,我看不到任何会序列化的内容,除非fetchData是sync..@T.J.Crowder,我明白了。我没有看到回调。i使用承诺或异步/等待。等待所有数据解析,然后设置数据:示例答案-我已经尝试过了,但是组件会在彼此之后刷新,而不是同时将
fetchData
函数添加到我的question@Baspa正如TJ所说,在这种情况下,在调用setState之前,请使用promise.all来更改函数以传递数组。另外,如果你不想使用承诺,你可以使用回调来实现,但这并没有那么好:)@Baspa-在发布我的答案后,我发现
fetchDataByName
有一个问题(事实上有两个),因此我在上面列出了这些问题。感谢您指出设置状态的问题@所以最好的方法应该是使用
promise.all
this.fetchData
上@基思