首页 > 解决方案 > 与 React 接口通信异步加载端

问题描述

有一个名为 JSONHeader 的类,它为我们加载每个 JSON 提供服务:

import jQuery from 'jquery-ajax';
import Atlas from "./Atlas";

export default class JSONHeader {
    constructor(location) {
        loadAtlasStructure(location);

        function loadAtlasStructure(location) {
            jQuery.ajax({
                dataType: "json",
                url: location,
                async: true,
                success: function (files) {
                    files.map((file) => {
                        jQuery.ajax({
                            dataType: "json",
                            url: location + file,
                            async: true,
                            success: function (data) {
                                console.log(data);
                                if (!window.IndexAtlas) {
                                    window.IndexAtlas = new Atlas();
                                }
                                window.IndexAtlas.addSubAtlas(data);
                                console.log('JSONHeader::window.IndexAtlas', window.IndexAtlas);
                            }
                        });
                    })
                }
            })
        }
    }
}

而且我想将React的顶级组件:App,从isLoading:true更改为isLoading:false,毕竟json已经加载。我们怎样才能实现这种行为?目前,每次重新加载所有 JSON 时,我都强制等待 5 秒

import React, {Component} from 'react';
import BrowserRouter from "react-router-dom/es/BrowserRouter";
import Switch from "react-router-dom/es/Switch";
import Route from "react-router-dom/es/Route";
import Redirect from "react-router-dom/es/Redirect";
import ScenePage from "../ScenePage/index";
import CoverPage from "../CoverPage/index";
import {INDEX, SCENE_PAGE} from "../../constantRoutes";
import JSONHeader from "../../newModel14Junio/JSONHeader";

export default class App extends Component {
    constructor(props) {
        super(props);

        const header = new JSONHeader('/atlas/json/');

        this.state = {
            isAtlasLoading: true
        };

        setTimeout(() => {
            this.setState({isAtlasLoading: false});
        }, 5000);
    }

    render() {
        if (this.state.isAtlasLoading) {
            return (<div>Atlas loading</div>);
        }
        return (
            <BrowserRouter>
                <div>
                    <Switch>
                        <Route exact path={INDEX} component={CoverPage}/>
                        <Route path={SCENE_PAGE} component={() => <ScenePage IndexAtlas={window.IndexAtlas}/>}/>
                        <Redirect from="*" to={INDEX}/>
                    </Switch>
                </div>
            </BrowserRouter>
        );
    }
}

谢谢您的帮助。

标签: javascriptreactjsasynchronousconcurrency

解决方案


使用 timeout 来做这件事不是一个好主意,因为你不知道它会花费多少时间来完成。因此,您可以向 JSONHeader 添加回调,如下所示:

import jQuery from 'jquery-ajax';
import Atlas from "./Atlas";

export default class JSONHeader {
    constructor(location, callback) {
        loadAtlasStructure(location);

        function loadAtlasStructure(location, callback) {
            jQuery.ajax({
                dataType: "json",
                url: location,
                async: true,
                success: function (files) {
                    files.map((file) => {
                        jQuery.ajax({
                            dataType: "json",
                            url: location + file,
                            async: true,
                            success: function (data) {
                                console.log(data);
                                if (!window.IndexAtlas) {
                                    window.IndexAtlas = new Atlas();
                                }
                                window.IndexAtlas.addSubAtlas(data);
                                console.log('JSONHeader::window.IndexAtlas', window.IndexAtlas);
                                callback();
                            }
                        });
                    })
                }
            })
        }
    }
}

在您的 ReactJS 中,您只需创建一个回调并在调用 JSONHeader 时传递它:

import React, {Component} from 'react';
import BrowserRouter from "react-router-dom/es/BrowserRouter";
import Switch from "react-router-dom/es/Switch";
import Route from "react-router-dom/es/Route";
import Redirect from "react-router-dom/es/Redirect";
import ScenePage from "../ScenePage/index";
import CoverPage from "../CoverPage/index";
import {INDEX, SCENE_PAGE} from "../../constantRoutes";
import JSONHeader from "../../newModel14Junio/JSONHeader";

export default class App extends Component {
    constructor(props) {
        super(props);

        const finishCallback = () => {
            this.setState({isAtlasLoading: false});
        };

        const header = new JSONHeader('/atlas/json/', finishCallback);

        this.state = {
            isAtlasLoading: true
        };        
    }

    render() {
        if (this.state.isAtlasLoading) {
            return (<div>Atlas loading</div>);
        }
        return (
            <BrowserRouter>
                <div>
                    <Switch>
                        <Route exact path={INDEX} component={CoverPage}/>
                        <Route path={SCENE_PAGE} component={() => <ScenePage IndexAtlas={window.IndexAtlas}/>}/>
                        <Redirect from="*" to={INDEX}/>
                    </Switch>
                </div>
            </BrowserRouter>
        );
    }
}

我希望我对你有所帮助。


推荐阅读