Menu
CoddyTech

计时器

本课属于 Coddy Node.js 学习旅程的“Node.js 基础”单元。第 27 课,共 33 课。

提醒应该在屏幕上逐步倒计时,然后停止。

setInterval(fn, ms) 每隔 ms 毫秒运行一次 fn,直到 clearInterval(id) 将其停止;setTimeout 只运行一次。只有没有剩余计时器时,程序才会结束,所以一直不清除的循环计时器会让程序持续运行。

let lap = 1;
const id = setInterval(() => {
    console.log(`Lap ${lap}`);
    lap += 1;
    if (lap > 3) {
        clearInterval(id);
    }
}, 500);

程序运行 5 秒后,终端会将其停止,这样你就能发现忘记调用 clearInterval 的情况。

challenge icon

挑战

简单

提醒会先在屏幕上倒计时,然后显示笔记。添加一个 remind 命令,用计时器实现这个功能。

  1. 在 notes.js 中添加一个 remind 命令。它后面的词是笔记编号,检查方式与 done 相同,因此你可以复用 noteNumber。
  2. 启动一个 setInterval,延迟时间为 200 毫秒。每次计时都打印一行:先打印 3,再打印 2,然后打印 1,最后打印笔记文本。
  3. 打印笔记后,用 clearInterval 停止计时器,这样程序就会结束。

有两条笔记 Buy milk 和 Call Ada 时,运行 node notes.js remind 2 会每隔 200 毫秒打印一行:

3
2
1
Call Ada
  1. 如果编号不是有效笔记编号,处理方式与 done 相同。有两条笔记时,运行 node notes.js remind 9 会向 stderr 打印 No note 9,并以退出代码 1 结束,不会开始倒计时。

试试看:在 $ node notes.js 后面的输入框中输入 remind 1,然后按 Enter。你会看到倒计时,然后看到第一条笔记。接着输入 remind 9:你会看到红色的 No note 9 和退出代码 1。如果忘记使用 clearInterval,程序就不会自行结束,终端会在 5 秒后将其停止。

亲手试试

// 你的笔记工具从这里开始。
import { rmSync } from 'node:fs';
import path from 'node:path';
import { formatNote } from './format.js';
import stats from './legacy/stats.cjs';
import store from './store.js';

const [command, ...words] = process.argv.slice(2);
const text = words.join(' ');

const noteNumber = (word) => {
    const n = Number(word);
    if (!Number.isInteger(n) || n < 1 || n > store.notes.length) {
        console.error(`No note ${word}`);
        process.exit(1);
    }
    return n;
};

if (command === 'add') {
    const n = await store.add(text);
    console.log(`Saved note ${n}.`);
} else if (command === 'list') {
    const owner = process.env.NOTES_OWNER ?? 'you';
    console.log(`Notes for ${owner}`);
    if (store.notes.length === 0) {
        console.log('No notes yet');
    }
    const lines = store.notes.map((note, i) => formatNote(i + 1, note));
    if (store.settings.sort === 'newest') {
        lines.reverse();
    }
    lines.forEach((line) => console.log(line));
} else if (command === 'where') {
    const file = path.join(process.cwd(), 'notes.json');
    console.log(file);
    console.log(path.basename(file));
} else if (command === 'stats') {
    console.log(`${store.notes.length} notes, ${stats.countWords(store.notes)} words`);
} else if (command === 'done') {
    const removed = await store.remove(noteNumber(words[0]));
    console.log(`Done: ${removed}`);
} else if (command === 'clear') {
    rmSync('notes.json', { force: true });
    console.log('Deleted notes.json');
} else {
    if (command) {
        console.error(`Unknown command: ${command}`);
    }
    console.error('Usage: node notes.js <command> [words]');
    process.exit(1);
}

Node.js 基础中的所有课

自己练习: Express 在线编辑器