How to use flushSyncCallbackQueue method in Playwright Internal

Best JavaScript code snippet using playwright-internal

Run Playwright Internal automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

scheduleUpdateOnFiber.js

Source: scheduleUpdateOnFiber.js Github

copy
1import { SyncLane } from './ReactFiberLane';
2import { ConcurrentMode, NoMode } from './ReactTypeMode';
3import { HostRoot, ClassComponent } from './ReactWorkTags';
4
5let syncLanePriority = 12;
6let NoLanePriority = 0;
7let syncQueue = [];
8let NoContext = 0;// 默认非批量
9let BatchContext = 1; // 批量
10let executionContext = NoContext; // 执行环境,默认是NoConetxt
11/**
12 * 在fiber调度更新
13 * @param {z} fiber 
14 * @param {*} lane 
15 * @param {*} eventTime 
16 */
17function scheduleUpdateOnFiber(fiber, lane, eventTime) {
18  //checkForNestedUpdates();
19  //warnAboutRenderPhaseUpdatesInDEV(fiber);
20  // 向上找到跟节点 root
21  var root = markUpdateLaneFromFiberToRoot(fiber, lane);
22  ensureRootIsScheduled(root, eventTime);
23  // 如果当前的执行上下文环境是NoContext(非批量)并且Mode不是并发的话
24  if (executionContext === NoContext && (fiber.mode & ConcurrentMode) === NoMode) {
25    flushSyncCallbackQueue();
26  }
27}
28
29
30// 从当前fiber节点,递归找到root
31function markUpdateLaneFromFiberToRoot(fiber) {
32  let parent = fiber.return;
33  while(parent) {
34    fiber = parent;
35    parent = fiber.return;
36    if (fiber.tag == HostRoot) {
37      return parent;
38    }
39  }
40  return null;
41}
42
43/**
44 * 
45 * @param {*} root 
46 * @param {*} eventTime 
47 */
48function ensureRootIsScheduled(root, eventTime) {
49  // 标记优先级低(低赛道),快过期的任务, 标记为更新
50  // markStarvedLanesAsExpired(root, currentTime); // Determine the next lanes to work on, and their priority.
51 
52  // 获取最高优先级的lane 当前是 1 //fiber里
53  var nextLanes = SyncLane;
54  // 当前跟节点上,正在执行的优先级 // 第一次undefined
55  let existingCallbackPrority = root.callbackPriority; 
56  // 获取最高级别的赛道的优先级 12
57  let newCallbackPropority = syncLanePriority; //按理说应该等于最高级别赛道的优先级
58  // 赛道和优先级不一样, 有关系
59  if (newCallbackPropority === existingCallbackPrority) {
60    // 也是在并发模式,即使在settimeout里也是批量的原因
61    return ;// 如果新的更新和当前根节点的更新相等,直接返回,复用上次的更新?,则不需要创建新的更新
62    // TODO 复用上次的更新
63  }
64  sceduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
65  // 微任务执行
66  queueMicrotask(flushSyncCallbackQueue);
67  // 
68  root.callbackPriority = newCallbackPropority;
69}
70
71// 时间放在微任务里
72function queueMicrotask() {
73  
74}
75
76function flushSyncCallbackQueue() {
77  syncQueue.forEach(cb => cb());
78  // 清空队列
79  syncQueue.length = 0;
80}
81
82
83// 其实就是把函数放在队列里,等待执行 
84// 调度
85function sceduleSyncCallback(fn) {
86  syncQueue.push(fn);
87}
88
89// 其实就是我们真正的渲染任务
90// 包括dom-diff ,比较老节点和新节点,得到dom-diff结果
91// 更新
92// 都在这里
93// 属于调和阶段  reconciler
94function performSyncWorkOnRoot(workInProgress) {
95  let root = workInProgress;
96  while (workInProgress) {
97    console.log('开始执行调和任务');
98    // 类组件
99    if(workInProgress.tag === ClassComponent) {
100      let inst = workInProgress.stateNode; // 获取此处类组件的实例
101      inst.state = processUpdateQueue(inst, workInProgress);
102      // 得到新的state后,就可以render得到虚拟dom,之后domdiff,更新dom
103      inst.render();
104    }
105    workInProgress = workInProgress.child;
106  }
107  commitRoot(root);
108}
109
110// 提交
111function commitRoot(root) {
112  // 根节点的优先级设置为默认值
113  root.callbackPriority = NoLanePriority;
114}
115
116/**
117 * 根据老状态和更细队列,计算新状态
118 * @param {*} inst 
119 * @param {*} workInProgress 
120 */
121function processUpdateQueue(inst, fiber) {
122  return fiber.update.reduce((state, update) => {
123    let payload = update.payload;
124    if (typeof update.payload === 'function') {
125      payload = update.payload(state);
126    }
127    return {
128      ...state, 
129      ...payload
130    }
131  }, inst.state);
132}
133
134// React.unstabe_batchUpdate
135export function batchUpdate(fn) {
136  let preContext = executionContext;
137  executionContext |= BatchContext; 
138  fn();
139  executionContext = preContext;
140}
141
142export default scheduleUpdateOnFiber;
Full Screen

ReactFiberWorkLoop.js

Source: ReactFiberWorkLoop.js Github

copy
1import { HostRoot, ClassComponent } from "./ReactWorkTags.js";
2const NoLanePriority = 1;
3const SyncLanePriority = 12;
4const syncQueue = [];
5
6const NoContext = 0;
7const BatchedContext = 1;
8let executionContext = NoContext;
9
10export default function scheduleUpdateOnFiber(fiber) {
11  const root = markUpdateLaneFromFiberToRoot(fiber);
12  isRootScheduled(root);
13  if (executionContext === NoContext) {
14    flushSyncCallbackQueue();
15  }
16}
17
18export function batchedUpdates(fn) {
19  let preExecuteContext = executionContext;
20  executionContext = BatchedContext;
21  fn();
22  executionContext = preExecuteContext;
23}
24
25function isRootScheduled(root) {
26  const newCallbackPriority = SyncLanePriority;
27  const existingCallbackPriority = root.callbackPriority;
28  if (newCallbackPriority === existingCallbackPriority) {
29    return;
30  }
31  scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
32  queueMicrotask(flushSyncCallbackQueue);
33  root.callbackPriority = newCallbackPriority;
34}
35
36function markUpdateLaneFromFiberToRoot(fiber) {
37  let parent = fiber.return;
38  while (parent) {
39    fiber = parent;
40    parent = parent.return;
41  }
42  if (fiber.tag === HostRoot) {
43    return fiber;
44  }
45  return null;
46}
47
48function performSyncWorkOnRoot(workInProgress) {
49  let root = workInProgress;
50  while (workInProgress) {
51    if (workInProgress.tag === ClassComponent) {
52      let inst = workInProgress.stateNode;
53      inst.state = processUpdateQueue(inst, workInProgress);
54      inst.render();
55    }
56    workInProgress = workInProgress.child;
57  }
58  commitRoot(root);
59}
60
61function commitRoot(root) {
62  root.callbackPriority = NoLanePriority;
63}
64
65function processUpdateQueue(inst, fiber) {
66  return fiber.updateQueue.reduce((state, { payload }) => {
67    return { ...state, ...payload };
68  }, inst.state);
69}
70
71function flushSyncCallbackQueue() {
72  syncQueue.forEach((cb) => cb());
73  syncQueue.length = 0;
74}
75
76function scheduleSyncCallback(cb) {
77  syncQueue.push(cb);
78}
79
Full Screen

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest

Run JavaScript Tests on LambdaTest Cloud Grid

Execute automation tests with Playwright Internal on a cloud-based Grid of 3000+ real browsers and operating systems for both web and mobile applications.

Test now for Free
LambdaTestX

We use cookies to give you the best experience. Cookies help to provide a more personalized experience and relevant advertising for you, and web analytics for us. Learn More in our Cookies policy, Privacy & Terms of service

Allow Cookie
Sarah

I hope you find the best code examples for your project.

If you want to accelerate automated browser testing, try LambdaTest. Your first 100 automation testing minutes are FREE.

Sarah Elson (Product & Growth Lead)