一、简介
由于 Bun 是服务端运行时,DOM 等相关的 Web API 与其无关,无需实现。以下是 Web API 在 Bun 运行时中的实现,如果你对这些 API 还不是很熟悉,那么这篇文章对你应该很有用!
本文更加适合:对 Bun 感兴趣和对 Web 标准感兴趣的同学。
二、延迟
2.1) 结构图
2.2) 不太常用的 setTimeout 使用第三个参数
ts
function call(name, greeting) {
console.log(`${greeting}, ${name}!`);
}
setTimeout(sayHello, 1000, 'John', 'Hello'); // 1秒后执行,输出 "Hello, John!"
使用第三个参数,或者更多的参数时,与 call 类似 function.call(thisArg, arg1, arg2, ...)
三、定时器
3.1) 结构图
3.2) 传递第三个参数
ts
function add(a, b) {
console.log(`${a} + ${b} = ${a + b}`);
}
const intervalId = setInterval(add, 1000, 5, 3);
setTimeout(() => {
clearInterval(intervalId); // 清除定时器
}, 5000); // 5秒后停止
四、加密
4.1) 结构图
web crypto 加密算法
4.3) 一个简单的 hash 加密 password 使用方法
以 digest 算法为例:
ts
digest(
algorithm: AlgorithmIdentifier,
data: BufferSource,
): Promise<ArrayBuffer>;
需要将 password 编码为 bufferSource(Uint8Array 类型),然后在经过 digest
进行加密(此处是异步的),最后再将数据装换成 hashHex 16 进制数据:
ts
// 使用 Web API 进行密码哈希
async function hashPassword(password) {
const encoder = new TextEncoder();
const data = encoder.encode(password);
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray.map(byte => byte.toString(16).padStart(2, '0')).join('');
return hashHex;
}
const password = 'your_password';
hashPassword(password)
.then(hash => {
console.log('哈希后的密码:', hash);
})
.catch(error => {
console.error('哈希密码时出错:', error);
});
五、调试
5.1) 调试结构图
- console
5.2) 性能结构图
- 加载时间
ts
// 使用 Navigation Timing API 获取页面加载性能信息
const navigationTiming = window.performance.timing;
console.log('页面加载时间:', navigationTiming.loadEventEnd - navigationTiming.navigationStart, '毫秒');
- 获取资源时间
ts
// 使用 Resource Timing API 获取资源加载性能信息
const resourceEntries = performance.getEntriesByType('resource');
resourceEntries.forEach(entry => {
console.log('资源 URL:', entry.name);
console.log('资源加载时间:', entry.duration, '毫秒');
});
六、微任务栈
将一个微任务(microtask)异步地加入到执行队列中。微任务是在当前代码执行完毕后,但在下一个渲染或 I/O 事件之前执行的任务。这使得它们非常适合安排需要在当前代码执行后立即执行的任务,但又不想影响浏览器执行其他任务,比如渲染或处理用户输入。
ts
console.log('开始');
// 微任务1:Promise
Promise.resolve().then(() => {
console.log('微任务1 完成');
});
// 微任务2:process.nextTick(在 Node.js 中使用)
process.nextTick(() => {
console.log('微任务2 完成');
});
// 微任务3:queueMicrotask
queueMicrotask(() => {
console.log('微任务3 完成');
});
console.log('结束');
// 宏任务1:setTimeout
setTimeout(() => {
console.log('宏任务1 完成');
}, 0);
console.log('最后');
七、错误
报告错误:reportError
ts
const newError = new Error("Some error message");
global.reportError(newError);
八、用户交互
- alert
ts
alert("enter 回车, 退出交互")
- prompt
ts
const a = prompt('提示', '第二个参数') // 输出并打印
console.log(a)
- confirm
ts
const isMing = confirm('选择小明吗?') // 选择小明吗? [y/N] y
console.log(isMing) //
与 web 端的逻辑基本上是一样的,但是没有真正的弹窗,提示,而是与终端进行交互。这个可能在写交互式命令行的时候特别有用。
九、Realms
9.1) ShadowRealms 类型
ts
declare class Realm {
constructor();
importValue(specifier: string, bindingName: string): Promise<PrimitiveValueOrCallable>;
evaluate(sourceText: string): PrimitiveValueOrCallable;
}
9.2) 简单示例
ts
// 创建 Realm 对象
const myRealm = new Realm();
// 使用 importValue 方法导入值
myRealm.importValue('someSpecifier', 'someBindingName')
.then((importedValue) => {
console.log('导入的值:', importedValue);
})
.catch((error) => {
console.error('导入值时发生错误:', error);
});
// 使用 evaluate 方法评估代码
const sourceCode = 'const x = 10; x * 2;';
const result = myRealm.evaluate(sourceCode);
console.log('评估的结果:', result);
十、事件
10.1) 结构图
10.2) 自定义事件
ts
const customEvent = new Event('customEvent');
global.addEventListener('customEvent', function(event) {
console.log('自定义事件被触发了!');
});
// 触发自定义事件
global.dispatchEvent(customEvent);
注意:此处不是 document 对象,触发,而是 global 全局事件处理
10.3) 事件目标和自定事件组合
ts
class MyEventTarget extends EventTarget {
constructor(secret) {
super();
this._secret = secret;
}
get secret() {
return this._secret;
}
updateSecret(newSecret) {
const event = new CustomEvent("updateSecret", { detail: newSecret });
this.dispatchEvent(event);
}
}
const myEventTarget = new MyEventTarget(5);
// 添加事件监听器
myEventTarget.addEventListener("updateSecret", (e) => {
myEventTarget._secret = e.detail;
});
const oldValue = myEventTarget.secret; // === 5
myEventTarget.updateSecret(7);
const newValue = myEventTarget.secret; // === 7
console.log(oldValue, newValue);
十一、小结
本文是继续讲解 Bun 中使用的 Web API 标准系列文章(一)的续补充,依然通过示例讲解常用 API 的用法,本文涉及了时间相关API,用户交互 API、加密算法,事件和调试等等。希望这篇文章能够帮助阅读的同学。