Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

调度系统 #39

Closed
RubyLouvre opened this issue Aug 22, 2017 · 2 comments
Closed

调度系统 #39

RubyLouvre opened this issue Aug 22, 2017 · 2 comments

Comments

@RubyLouvre
Copy link
Owner

RubyLouvre commented Aug 22, 2017

mainQueue就是传送带,currentQueue或其他queue就是托运箱,job就是要加工的材料,exec是决定如何加工。

export function drainQueue() {
    
    var queue = mainQueue.shift()
    //如果父元素拥有多个子组件,如果第一个组件在mounted/updated钩子里再次更新父元素,
    //那么mainQueue可能没有子数组了,需要置换queue为currentQueue,执行里面的mounted/updated钩子
    if(!queue &&  currentQueue.length){
        queue = currentQueue;
    }
    options.beforePatch();
    //先执行所有元素虚拟DOMrefs方法(从上到下)
    Refs.clearElementRefs();
    let needSort = [],
        unique = {},
        job, updater;

    while( job = queue.shift() ){
        updater = job.host;
        //queue可能中途加入新元素,  因此不能直接使用queue.forEach(fn)
        if (updater._disposed) {
            continue;
        }
        if (!unique[updater._mountOrder]) {
            unique[updater._mountOrder] = 1;
            needSort.push(job);
        }
        // currentQueue = queue;
           
        // var command = job.exec === updater.onUpdate ? "update" : job.exec === updater.onEnd ? "end" : "receive";
        // console.log(updater.name, command,updater._hookName );
        job.exec.call(updater,queue);
        // if(!queue.length){
        /*  while((el =  mainQueue.shift())){
                    if(el.length){
                        queue = el;
                        break;
                    }
                }
           */
        // }
    }

    if (mainQueue.length > 1) {
       mainQueue.push(currentQueue);
    }
    //再执行所有setState/forceUpdate回调,根据从下到上的顺序执行
    needSort.sort(mountSorter).forEach(function(job) {
        var updater = job.host;
        clearArray(updater._pendingCallbacks).forEach(function(fn) {
            fn.call(updater._instance);
        });
    });
    options.afterPatch();
}
@RubyLouvre
Copy link
Owner Author

RubyLouvre commented Aug 23, 2017

例子

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <!--  <script type='text/javascript' src="./lib/shallowCompare.js"></script>-->
    <script type='text/javascript' src="./dist/React.js"></script>
    <!-- <script type='text/javascript' src="./lib/ReactTestUtils.js"></script>-->
   <!--<script type='text/javascript' src="./test/react.js"></script>
    <script type='text/javascript' src="./test/react-dom.js"></script>-->

    <!--<script type='text/javascript' src="./test/react-lite.js"></script>-->
    <script type='text/javascript' src="./lib/babel.js"></script>

</head>

<body>

    <div>开发者工具</div>
    <pre>
          
        </pre>
    <div id='example'></div>


    <script type='text/babel'>
   
     
    var container = document.getElementById("example")
    var div = container
    // var PropTypes = React.PropTypes
    if(!window.ReactDOM){
       window.ReactDOM = window.React
       var PropTypes = React.PropTypes
    }

    var expect = function(a) {
        return {
            toBe: function(b) {
                console.log(a, b, a === b)
            }
        }
    }
   
    class App extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                flag: 1
            };
        }
        componentDidMount(props){
            console.log("App did mount")
        }
        componentWillUpdate(props){
            console.log("App will update")
        }
        componentDidUpdate(props){
            console.log("App did update")
        }
        render() {
            return (<div>{
                this.state.flag ?
                [<Child key="a" text="111" />,
                <Child key="b" text="222" />]:
                [<Child key="a" text="333" />,
                <Child key="b" text="444" />]
                 }</div>
            );
        }
    }
    class Child extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                text: props.text 
            };
        }
        render(){
            return <span className={this.state.text}>{this.state.text}</span>
        }
        componentDidMount(props){
            console.log("Child did mount")
        }
        componentWillReceiveProps(props){
            console.log("Child ",this.props.text, "will receive")
             this.setState({
                 text: props.text
             })
        }
        componentWillUpdate(props){
            console.log("Child ",this.props.text, "will update")
        }
        componentDidUpdate(props){
            console.log("Child ",this.props.text, "did update")
        }
    }

    var s = ReactDOM.render(<App />, div);
     s.setState({
         flag: 0
     })
  
    </script>
</body>
</html>

image

@RubyLouvre
Copy link
Owner Author

RubyLouvre commented Aug 25, 2017

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <!--  <script type='text/javascript' src="./lib/shallowCompare.js"></script>-->

 <script type='text/javascript' src="./dist/React.js"></script>
</head>

<body>
  <div>开发者工具</div>
  <pre>
     A did mount
     B did mount
     C did mount
     A will receive
     B will receive
     C will receive
     A did update
     B did update
     C did update
     A will receive
     B will receive
     C will receive
     A did update
     B did update
     C did update
</pre>
  <div id='example'></div>
  <script type='text/babel'>
   
     
      var container = document.getElementById("example")
      var div = container
     // var PropTypes = React.PropTypes
      if(!window.ReactDOM){
        window.ReactDOM = window.React
       
      }
      var PropTypes = React.PropTypes
      var expect = function(a) {
          return {
              toBe: function(b) {
                  console.log(a, "\nvs\n",b, a === b)
              }
          }
      }
      var list  = []
      function logger(a){
        console.log(a)
      }
     
      var a  = 1;
      class A extends React.Component {
          constructor(props) {
              super(props);
              this.state = {
                  text: "aaa"
              };
          }

          componentDidMount() {
              logger("A did mount");
              ReactDOM.render(<div><A text="111"/><B text="222"/><C text="333"/></div>, div);
          
          }
          componentWillReceiveProps(){
              logger("A will receive");
          }

          componentDidUpdate() {
              logger("A did update");
              if(a){
                  a = 0;
                  ReactDOM.render(<div><A text="111"/><B text="222"/><C text="333"/></div>, div);
              }

          }
          render() {
              return <div>{this.state.text}</div>;
          }
      }
      class B extends React.Component {
          constructor(props) {
              super(props);
              this.state = {
                  text: "bbb"
              };
          }

          componentDidMount() {
              logger("B did mount");
          }
          componentWillReceiveProps(){
              logger("B will receive");
          }

          componentDidUpdate() {
              logger("B did update");
          }
          render() {
              return <div>{this.state.text}</div>;
          }
      }
      class C extends React.Component {
          constructor(props) {
              super(props);
              this.state = {
                  text: "ccc"
              };
          }
          componentWillReceiveProps(){
              logger("C will receive");
          }
          componentDidMount() {
              logger("C did mount");
          }
          componentDidUpdate() {
              logger("C did update");
          }
          render() {
              return <div>{this.state.text}</div>;
          }
      }
      var s = ReactDOM.render(<div><A/><B/><C/></div>, div);
     
    </script>

</body>

</html>

此例子用于验证drainQueue开头几句话

export function drainQueue() {
    
    var queue = mainQueue.shift();
    //如果父元素拥有多个子组件,如果第一个组件在mounted/updated钩子里再次更新父元素,
    //那么mainQueue可能没有子数组了,需要置换queue为currentQueue,执行里面的mounted/updated钩子
    if(!queue &&  currentQueue.length){
        queue = currentQueue;
    }
    options.beforePatch();
    //先执行所有元素虚拟DOMrefs方法(从上到下)
    Refs.clearElementRefs();
    let needSort = [],
  //....略
}

@RubyLouvre RubyLouvre changed the title 不使用异步的setState 调度系统 Oct 30, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant