JS简介的原子对象
#javascript #网络开发人员 #编程 #braziliandevs

我们亲爱的JavaScript是单线螺纹,因此,一次只能执行一件事。保留这个,这很重要!

因此,如果长期运行任务阻止了主导航器链,则浏览器将难以渲染。

例如,如果我们在大型数据结构中粉丝执行操作,
或创建一个非常大的简单循环。
这可能会导致渲染冻结。只要循环最终出现,或者算法传播大数据结构,您就无能为力,只需等待即可。

这是一个螺纹单个问题。
只是一次做一件事,如果她花了很长时间,您就可以做得更多!

我们不会谈论本文中的回调和承诺。

解决此问题的解决方案之一是使用Web Works。

Web工作人员是允许脚本操作与Web应用程序主线程不同线程的机制。允许在不阻止主线程(通常与接口相关联)的情况下处理费力的计算。
字体> mdn。

我们知道JS是单线螺纹。
随着时间的流逝,浏览器应用程序变得越来越苛刻。
因此,他们决定带上网络作品来帮助我们!

现在,巨型循环可以转到另一个线程,并使我们的主屏幕美丽而光明,而没有任何人©m Divess!

Web工作人员允许在浏览器上下文中并行执行。

但是,由于技术中的所有内容,网络工作都是他们的缺点。例如,将数据传输到线程工作者的成本。所有转移均通过后邮政进行。

浏览器使用结构化的克隆算法

The structured clone algorithm - Web APIs | MDN

结构化克隆算法复制复杂的JavaScript对象。 它在调用structredClone()时在内部使用,以通过postmessage()在工人之间传输数据,用索引dexedDB存储对象或为其他API复制对象。

favicon developer.mozilla.org

要加倍一个对象,即内存中相同数据的复制。根据情况,这一成本可以克服转移向线程工人的转移。

如果我们能够避免数据卡?
解决这个问题的一种方法是利用 sharedArrayBuffer

对于JavaScript开发人员,此构建使我们能够创建共享内存的部分。我们可以在双方更新相同的共享内存。

// 
const length = 10;
 // Criando o tamanho do nosso buffer
const size = Int32Array.BYTES_PER_ELEMENT * length;
 // Criando o buffer com 10 inteiros 
const sharedBuffer = new SharedArrayBuffer(size);
const sharedArray = new Int32Array(sharedBuffer);

oâ©int32Array:

Int32Array - JavaScript | MDN

INT32Array键入数组代表平台字节顺序中的两件填充32位签名整数的数组。如果需要控制字节订单,请改用DataView。内容初始化为0。建立后,您可以使用对象的方法在数组中引用元素,也可以使用标准数组索引语法(即使用括号符号)。

favicon developer.mozilla.org

或该共享arraybuffer:

我们现在有一个可以共享的记忆脚步。也就是说,主线程和Web Works可以一起访问同一个地方!

这很好,保存回忆!
但是,就像技术中的所有内容一样,它都有缺点!

想象以下内容:通过访问同一内存位置,我们有3个或更多的主线程Web工作室。这会出错。
非常错误。我们可以有种族条件。所有争夺同一地点或使用相同信息更新同一位置的问题。
换句话说,2作品可以同时完成相同的工作,这是浪费。

正在运行什么:

a 种族条件种族危害是电子,软件或其他系统的条件行为取决于其他不可控制事件的序列或时间。当一个或多个可能的行为不可取时,它就会成为一个错误。

输入原子对象。

心理操作确保我们有一种标准化的方式来以可预测的顺序读取和记录数据

Anomics管理着每个人对内存的访问权限,从而防止了跑步条件,浪费工作等。

o - 原子:

Atomics - JavaScript | MDN

原子名称空间对象包含用于执行原子操作的静态方法。它们与共享arraybuffer和arraybuffer对象一起使用。

favicon developer.mozilla.org

// main.js
const worker = new Worker('worker.js');
const length = 10;
const size = Int32Array.BYTES_PER_ELEMENT * length;

const sharedBuffer = new SharedArrayBuffer(size);
const sharedArray = new Int32Array(sharedBuffer);
for (let i = 0; i < 10; i++) {
    Atomics.store(sharedArray, i, 0);
}
worker.postMessage(sharedBuffer);

访问Worker的数据

// worker.js
self.addEventListener('message', (event) => {
    const sharedArray = new Int32Array(event.data);
    for (let i = 0; i < 10; i++) {
        const arrayValue = Atomics.load(sharedArray, i);
        console.log(`The item at array index ${i} is ${arrayValue}`);
    }
}, false);


如果我们想更新工人的矩阵怎么办?我们有两个使用Atomics的这些更新的选项。我们可以使用以前看到的商店,也可以使用Exchange。这里的区别在于,它存储存储的值并换取了替换的值。让我们看看这在实践中的工作方式:

// worker.js
self.addEventListener('message', (event) => {
    const sharedArray = new Int32Array(event.data);
    for (let i = 0; i < 10; i++) {
        if (i%2 === 0) {
            const storedValue = Atomics.store(sharedArray, i, 1);
            console.log(`The item at array index ${i} is now ${storedValue}`);
        } else {
            const exchangedValue = Atomics.exchange(sharedArray, i, 2);
            console.log(`The item at array index ${i} was ${exchangedValue}, now 2`);
        }
    }
}, false);

我们现在可以阅读并更新主线程矩阵和工作线程。 Atomics还有其他一些妈妈可以利用我们的优势来管理我们的新共享阵列。其中两个比Waiite唤醒更多。 Waitnos允许您等待阵列的更改并继续操作。实际上,这看起来像是工人的一边:

self.addEventListener('message', (event) => {
    const sharedArray = new Int32Array(event.data);
    const arrayIndex = 0;
    const expectedStoredValue = 50;
    // An optional 4th argument can be passed which is a timeout
    Atomics.wait(sharedArray, arrayIndex, expectedStoredValue);
    // Log the new value
    console.log(Atomics.load(sharedArray, arrayIndex));
}, false);

在这里,我们正在等待ArrayIndex0的更改,其中预期的存储值为50。我们可以告诉他在更改离子中的值时从主线程中醒来:

const newArrayValue = 100;
Atomics.store(sharedArray, 0, newArrayValue);
// The index that is being waited on
const arrayIndex = 0;
// The first agent waiting on the value
const queuePos = 1;
Atomics.wake(sharedArray, arrayIndex, queuePos);

其他功能是通过便利性提供的,例如分别从矩阵中加入或减去。如果您对BIT操作感兴趣,则提供其中一些,包括OR和XOR。

我们可以看到原子可以避免使用所有原子的跑步条件并在数组中进行可预测的更新。

要使用字符串,我们需要将它们转换为许多数值表示,例如,已知的编码为UTF-16。

function sharedArrayBufferToUtf16String(buf) {
    const array = new Uint16Array(buf);
    return String.fromCharCode.apply(null, array);
}

function utf16StringToSharedArrayBuffer(str) {
    // 2 bytes for each char
    const bytes = str.length *2;
    const buffer = new SharedArrayBuffer(bytes);
    const arrayBuffer = new Uint16Array(buffer);
    for (let i = 0, strLen = str.length; i < strLen; i++) {
        arrayBuffer[i] = str.charCodeAt(i);
    }
    return { array: arrayBuffer, buffer: buffer };
}

const exampleString = "Hello world, this is an example string!";
const sharedArrayBuffer = utf16StringToSharedArrayBuffer(exampleString).buffer;
const backToString = sharedArrayBufferToUtf16String(sharedArrayBuffer);

所有的cadigos均从本文中获取:

The Return of SharedArrayBuffers and Atomics - SitePen

查看我们如何利用共享arraybuffers在各种线程上下文之间共享内存,同时使用原子方法避免种族条件。

favicon sitepen.com

我对原子对象进行了小介绍
记住所有这些 *也可以在节点中工作! *
如果您想了解更多信息,只需阅读资源:

https://www.sitepen.com/blog/the-return-of-sharedarraybuffers-and-atomics

https://dev.to/feezyhendrix/worker-threads-in-node-js-2ikh

https://exploringjs.com/es2016-es2017/ch_shared-array-buffer.html

https://blogtitle.github.io/using-javascript-sharedarraybuffers-and-atomics/

https://blog.logrocket.com/understanding-sharedarraybuffer-and-cross-origin-isolation/

https://www.tutorialspoint.com/what-is-the-use-of-atomics-in-javascript

https://webreflection.medium.com/about-sharedarraybuffer-atomics-87f97ddfc098

https://www.geeksforgeeks.org/atomics-in-javascript/

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics