structuredClone
structuredClone 是 HTML5 中新增的一个 API,它可以用来实现 Web Worker 之间的通信。
文档
structuredClone 的使用
const obj = {
a: 1,
b: {
c: 1,
},
};
const res = structuredClone(obj);
console.log(res); // {a: 1, b: {c: 1}}
obj.a = 2;
console.log(obj); // {a: 2, b: {c: 1}}
console.log(res); // {a: 1, b: {c: 1}}
obj.b.c = 2;
console.log(obj); // {a: 2, b: {c: 2}}
console.log(res); // {a: 1, b: {c: 1}}
另外一种实现
import structuredClone from '@ungap/structured-clone';
看到了一个用 MessageChannel 实现的深拷贝,简直就是秀儿啊
class StructuredCloner {
constructor() {
this.pendingClones_ = new Map();
this.nextKey_ = 0;
const channel = new MessageChannel();
this.inPort_ = channel.port1;
this.outPort_ = channel.port2;
this.outPort_.onmessage = ({ data: { key, value } }) => {
const resolve = this.pendingClones_.get(key);
resolve(value);
this.pendingClones_.delete(key);
};
this.outPort_.start();
}
cloneAsync(value) {
return new Promise((resolve) => {
const key = this.nextKey_++;
this.pendingClones_.set(key, resolve);
this.inPort_.postMessage({ key, value });
});
}
}
const structuredCloneAsync = (window.structuredCloneAsync =
StructuredCloner.prototype.cloneAsync.bind(new StructuredCloner()));
测试
const main = async () => {
const original = { date: new Date(), number: Math.random() };
original.self = original;
const clone = await structuredCloneAsync(original);
// They're different objects:
console.assert(original !== clone);
console.assert(original.date !== clone.date);
// They're cyclical:
console.assert(original.self === original);
console.assert(clone.self === clone);
// They contain equivalent values:
console.assert(original.number === clone.number);
console.assert(Number(original.date) === Number(clone.date));
console.log("Assertions complete.");
};
main();
参考文章
上一篇
正则表达式匹配字符串开头、中间包含特定内容和结尾的字符串
使用正则表达式匹配以特定字符串开头,中间包含特定内容(例如'worker_threads'),并以特定字符串结尾的 JavaScript 代码片段。文章提供了解决方案并分析了不同正则表达式的优劣。
下一篇
JS 解决 'Failed to execute 'put' on 'IDBObjectStore'...' 问题
本文介绍如何解决 JavaScript 中 IndexedDB 的 'Failed to execute 'put' on 'IDBObjectStore': An object could not be cloned' 错误。该错误通常是因为存储对象包含不可序列化的数据类型(例如 Promise 对象)引起的。文章提供了几种解决方案,包括使用 `realistic-structured-clone` 库进行深拷贝,以及其他替代方案的比较。