[Bun 系列]:了解这些 Web API,助力你开发 Bun 运行时应用(二)

一、简介

由于 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、加密算法,事件和调试等等。希望这篇文章能够帮助阅读的同学。

相关推荐
程序员爱技术1 小时前
Vue 2 + JavaScript + vue-count-to 集成案例
前端·javascript·vue.js
并不会2 小时前
常见 CSS 选择器用法
前端·css·学习·html·前端开发·css选择器
衣乌安、2 小时前
【CSS】居中样式
前端·css·css3
兔老大的胡萝卜2 小时前
ppk谈JavaScript,悟透JavaScript,精通CSS高级Web,JavaScript DOM编程艺术,高性能JavaScript pdf
前端·javascript
低代码布道师2 小时前
CSS的三个重点
前端·css
耶啵奶膘3 小时前
uniapp-是否删除
linux·前端·uni-app
NiNg_1_2344 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
王哈哈^_^5 小时前
【数据集】【YOLO】【目标检测】交通事故识别数据集 8939 张,YOLO道路事故目标检测实战训练教程!
前端·人工智能·深度学习·yolo·目标检测·计算机视觉·pyqt
Chrikk5 小时前
Go-性能调优实战案例
开发语言·后端·golang
幼儿园老大*5 小时前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go