https://stackblitz.com/edit/js-ntqfil?file=index.js

    1. const a1 = {name: 'a1', child: null, sibling: null, return: null};
    2. const b1 = {name: 'b1', child: null, sibling: null, return: null};
    3. const b2 = {name: 'b2', child: null, sibling: null, return: null};
    4. const b3 = {name: 'b3', child: null, sibling: null, return: null};
    5. const c1 = {name: 'c1', child: null, sibling: null, return: null};
    6. const c2 = {name: 'c2', child: null, sibling: null, return: null};
    7. const d1 = {name: 'd1', child: null, sibling: null, return: null};
    8. const d2 = {name: 'd2', child: null, sibling: null, return: null};
    9. a1.child = b1;
    10. b1.sibling = b2;
    11. b2.sibling = b3;
    12. b2.child = c1;
    13. b3.child = c2;
    14. c1.child = d1;
    15. d1.sibling = d2;
    16. b1.return = b2.return = b3.return = a1;
    17. c1.return = b2;
    18. d1.return = d2.return = c1;
    19. c2.return = b3;
    20. let nextUnitOfWork = a1;
    21. workLoop();
    22. function workLoop() {
    23. while (nextUnitOfWork !== null) {
    24. nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
    25. }
    26. }
    27. function performUnitOfWork(workInProgress) {
    28. let next = beginWork(workInProgress);
    29. if (next === null) {
    30. next = completeUnitOfWork(workInProgress);
    31. }
    32. return next;
    33. }
    34. function beginWork(workInProgress) {
    35. log('work performed for ' + workInProgress.name);
    36. return workInProgress.child;
    37. }
    38. function completeUnitOfWork(workInProgress) {
    39. while (true) {
    40. let returnFiber = workInProgress.return;
    41. let siblingFiber = workInProgress.sibling;
    42. nextUnitOfWork = completeWork(workInProgress);
    43. if (siblingFiber !== null) {
    44. // If there is a sibling, return it
    45. // to perform work for this sibling
    46. return siblingFiber;
    47. } else if (returnFiber !== null) {
    48. // If there's no more work in this returnFiber,
    49. // continue the loop to complete the returnFiber.
    50. workInProgress = returnFiber;
    51. continue;
    52. } else {
    53. // We've reached the root.
    54. return null;
    55. }
    56. }
    57. }
    58. function completeWork(workInProgress) {
    59. log('work completed for ' + workInProgress.name);
    60. return null;
    61. }
    62. function log(message) {
    63. let node = document.createElement('div');
    64. node.textContent = message;
    65. document.body.appendChild(node);
    66. }