长时间运行作业后渲染组件

时间:2018-04-03 08:02:00

标签: javascript reactjs

我目前正在开发一款笔记本式应用,其中数据通过ajax加载。其中一些笔记本电脑是加密的。所以我必须在最终渲染之前解密这些数据。这是我目前的组成部分:

import React from "react";
import ReactDOM from "react-dom";
import "regenerator-runtime/runtime";

class Notebooks extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            loading: true,
            data: ""
        }
    }

    loadData() {

        $.ajax("/notebook/", {
            contentType: "application/json",
            success: function (data) {
                let bunny = [];
                data.map(async (hiren, index) => {
                    let plaintext = {};
                    if (hiren["fields"]["encrypted"]) {
                        let data = {};
                        let name_options = {
                            message: openpgp.message.readArmored(hiren["fields"]["name"]),
                            passwords: [sessionStorage.getItem("key")],
                            format: "utf8"
                        };
                        let description_options = {
                            message: openpgp.message.readArmored(hiren["fields"]["description"]),
                            passwords: [sessionStorage.getItem("key")],
                            format: "utf8"
                        };

                        let _name = await openpgp.decrypt(name_options);
                        let _description = await openpgp.decrypt(description_options);
                        data["pk"] = hiren["pk"];
                        data["fields"] = { "name": _name.data, "description": _description.data };
                        bunny.push(data);

                    } else {
                        plaintext["pk"] = hiren["pk"];
                        plaintext["fields"] = {
                            "name": hiren["fields"]["name"],
                            "description": hiren["fields"]["description"]
                        };
                        bunny.push(plaintext);
                    }
                });
                this.setState({ data: bunny });
                this.setState({ loading: false });
            }.bind(this),
            error: function (data) {
                console.error(data);
            }
        });

        componentDidMount(){
            this.loadData();
        }

        final_component(){
            // some jsx 
        }

        render() {
            if (this.state.loading) {
                return (
                    <div>Loading...</div>
                )
            }
            return (
                <div>{this.final_component()}</div>
            );
        }
    }
}

在我目前的代码中,只有未加密的笔记本正在渲染。那么如何重新组织我的组件,以便在解密所有数据后,我可以渲染我的最终组件块。

1 个答案:

答案 0 :(得分:2)

this.setState()结算之前,

data.map()被解雇了。

Promise.all()可用于runawait arrays promises的解析。

请参阅下面的实际示例。

&#13;
&#13;
// Load Chunk.
const loadChunk = (x) => new Promise(resolve => setTimeout(() => resolve(`chunk ${x}`), 1000))

// Load Comp.
class LoadComp extends React.Component {

  // State.
  state = {
    loading: true,
    data: false
  }

  // Render.
  render() {
    if (this.state.loading) return <div>Loading ..</div>
    return <div>{this.state.data.map((x, i) => <div key={i}>{x}</div>)}</div>
  }
  
  // Did Mount.
  componentDidMount() {
    this.fetchData()
  }
  
  // Fetch Data.
  fetchData = () => Promise.all([1, 2, 3, 4].map(x => loadChunk(x))).then(data => this.setState({data, loading: false}))
  
}

// Mount.
ReactDOM.render(<LoadComp/>, document.querySelector('#root'))
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.js"></script>
<div id="root"></div>
&#13;
&#13;
&#13;