// job就是组件实例上的update方法(effect函数) exportfunctionqueueJob(job: SchedulerJob) { // the dedupe search uses the startIndex argument of Array.includes() // by default the search index includes the current job that is being run // so it cannot recursively trigger itself again. // if the job is a watch() callback, the search will start with a +1 index to // allow it recursively trigger itself - it is the user's responsibility to // ensure it doesn't end up in an infinite loop. // 去重判断 if ( !queue.length || !queue.includes( job, isFlushing && job.allowRecurse ? flushIndex + 1 : flushIndex ) ) { if (job.id == null) { // 如果组件实例没有id,添加到队列尾部 queue.push(job) } else { // 按照id自增的顺序排列job queue.splice(findInsertionIndex(job.id), 0, job) } queueFlush() } }
functionflushJobs(seen?: CountMap) { isFlushPending = false isFlushing = true if (__DEV__) { seen = seen || newMap() }
// Sort queue before flush. // This ensures that: // 1. Components are updated from parent to child. (because parent is always // created before the child so its render effect will have smaller // priority number) // 2. If a component is unmounted during a parent component's update, // its update can be skipped. // 给队列进行排序 queue.sort(comparator) // 更新前确保队列是正确的 // 先创建父组件再创建子组件 // 如果父组件更新时子组件被卸载了,那么子组件的更新可以被跳过 // conditional usage of checkRecursiveUpdate must be determined out of // try ... catch block since Rollup by default de-optimizes treeshaking // inside try-catch. This can leave all warning code unshaked. Although // they would get eventually shaken by a minifier like terser, some minifiers // would fail to do that (e.g. https://github.com/evanw/esbuild/issues/1610) const check = __DEV__ ? (job: SchedulerJob) =>checkRecursiveUpdates(seen!, job) : NOOP