Skip to content

Commit

Permalink
feat: support watchEffect api
Browse files Browse the repository at this point in the history
  • Loading branch information
cuixiaorui committed Jul 29, 2022
1 parent eaf025e commit 9f16475
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 5 deletions.
7 changes: 5 additions & 2 deletions packages/runtime-core/__tests__/apiWatch.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { reactive } from "@mini-vue/reactivity";
import { watchEffect } from "../src/apiWatch";
import { nextTick } from "../src/scheduler";

describe("api: watch", () => {
it.todo("effect", async () => {
// 先实现个 watchEffect 玩一玩
it("effect", async () => {
const state = reactive({ count: 0 });
let dummy;
watchEffect(() => {
Expand Down
29 changes: 29 additions & 0 deletions packages/runtime-core/src/apiWatch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { ReactiveEffect } from "@mini-vue/reactivity";
import { queuePreFlushCb } from "./scheduler";

// Simple effect.
export function watchEffect(effect) {
doWatch(effect);
}

function doWatch(source) {
// 把 job 添加到 pre flush 里面
// 也就是在视图更新完成之前进行渲染(待确认?)
// 当逻辑执行到这里的时候 就已经触发了 watchEffect
const job = () => {
effect.run();
};

// 这里用 scheduler 的目的就是在更新的时候
// 让回调可以在 render 前执行 变成一个异步的行为(这里也可以通过 flush 来改变)
const scheduler = () => queuePreFlushCb(job);

const getter = () => {
source();
};

const effect = new ReactiveEffect(getter, scheduler);

// 这里执行的就是 getter
effect.run();
}
9 changes: 6 additions & 3 deletions packages/runtime-core/src/scheduler.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
const queue: any[] = [];
const activePreFlushCbs:any = [];
const activePreFlushCbs: any = [];

const p = Promise.resolve();
let isFlushPending = false;

export function nextTick(fn) {
export function nextTick(fn?) {
return fn ? p.then(fn) : p;
}

Expand Down Expand Up @@ -37,6 +37,9 @@ function queueCb(cb, activeQueue) {
// todo 这里没有考虑 activeQueue 是否已经存在 cb 的情况
// 然后在执行 flushJobs 的时候就可以调用 activeQueue 了
activeQueue.push(cb);

// 然后执行队列里面所有的 job
queueFlush()
}

function flushJobs() {
Expand All @@ -60,6 +63,6 @@ function flushJobs() {
function flushPreFlushCbs() {
// 执行所有的 pre 类型的 job
for (let i = 0; i < activePreFlushCbs.length; i++) {
activePreFlushCbs[i]()
activePreFlushCbs[i]();
}
}

0 comments on commit 9f16475

Please sign in to comment.