How to quickly get started with VUE3.0: Enter Learning
When multiple contexts access SharedArrayBuffer, if operations are performed on the buffer at the same time, resource contention problems may occur. The Atomics API allows multiple contexts to safely read and write a SharedArrayBuffer by forcing that only one operation can be performed on the buffer at a time.
The nature of atomic operations precludes optimizations (such as instruction reordering) that the operating system or computer hardware would normally perform automatically. Atomic operations also make it impossible to access memory concurrently. If used improperly, it may cause program execution to slow down. For this reason, the original design intention of the Atomics API is to build complex multi-threaded JavaScript programs based on minimal but stable atomic behavior. .
Atomics API provides a set of simple methods for performing in-place modification operations. In the ECMA specification, these methods are defined as AtomicReadModifyWrite operations. Under the hood, these methods read a value from a location in the SharedArrayBuffer, perform arithmetic and bitwise operations, and finally write the result to the same location. The atomic nature of these operations means that the read, modify, and write back operations described above will be executed in order and will not be interrupted by other threads.
//Create a buffer of size 1 let sharedArrayBuffer = new SharedArrayBuffer(1); //Create Unit8Arraylet based on buffer typedArray = new Unit8Array(sharedArrayBuffer); //All ArrayBuffers are initialized to 0console.log(typedArray); //Unit8Array[0] //Perform atomic addition of 10 to the value at index 0Atomics.add(typedArray,0,10); //Unit8Array[10] //Perform atomic subtraction of 10 on the value at index 0Atomics.sub(typedArray,0,10); //Unit8Array[0]
The browser's JavaScript compiler and the CPU architecture itself have the authority to rearrange instructions to improve program execution efficiency. Under normal circumstances, JavaScript's single-threaded environment can perform this optimization at any time, but instruction rearrangement in multi-threads may lead to resource contention and is extremely difficult to troubleshoot.
The Atomics API solves this problem in two main ways:
The order of all atomic instructions relative to each other is never rearranged.
Using atomic reads or writes guarantees that all instructions are not reordered relative to atomic reads and writes.
In addition to reading and writing buffer values, Atomics.load() and Atomics.store() can also build "code fences". The JavaScript engine ensures that non-atomic instructions can be rearranged locally relative to load() and store(), but this rearrangement will not violate the boundaries of atomic reads and writes.
const sharedArrayBuffer = new SharedArrayBuffer(4); const view = new Unit32Array(sharedArrayBuffer); //Perform non-atomic write view[0] = 1; //Non-atomic writing can be guaranteed to be completed before this read operation, so 1console.log(Atomics.load(view,0)); will definitely be read here. //1 //Perform atomic write Atomics.store(view,0,2); //Non-atomic reading can be guaranteed to occur after atomic writing is completed, and 2console.log(view[0]); will definitely be read here. //2
In order to ensure continuous and uninterrupted reading first and then writing, the Atomics API provides two methods: exchange() and compareExchange(). Atomics.exchange() performs a simple exchange that guarantees that other threads will not interrupt the exchange.
const sharedArrayBuffer = new SharedArrayBuffer(4); const view = new Unit32Array(sharedArrayBuffer); //Write 10Atomics.store(view,0,10) at index 0; //Read the value from index 0 and write 5 at index 0console.log(Atomics.exchange(view,0,5)); //10 //Read the value from index 0 console.log(Atomics.load(view,0)); //5
In a multi-threaded program, a thread may only want to write to a shared buffer if no other thread has modified the value since the last time it was read. If the value has not been modified, this thread can safely write the updated value: if the value has been modified, performing a write operation will destroy the value calculated by other threads. For this kind of task, the Atomics API provides the compare-Exchange() method. This method only performs the write operation if the value at the target index matches the expected value.
Without some kind of locking mechanism, multi-threaded programs cannot support complex requirements. To this end, the Atomics API provides methods that mimic Linux Futex (fast user-space mutex). These methods, while very simple in themselves, can serve as basic components for more complex locking mechanisms.
All atomic Futex operations can only be used on Int32Array views, and moreover, only within worker threads.
Cross-document messaging, sometimes also called XDM (cross-document messaging), is the ability to transfer information between different execution contexts (such as different worker threads or pages from different sources).
Encoding API is mainly used to convert between strings and stereotyped arrays.
File API is still based on the file input field in the form, but adds the ability to directly access file information. HTML5 adds a files collection to the DOM for file input elements. When the user selects one or more files in the file field, the files collection will contain a set of File objects representing the selected files. Each File object has some read-only attributes.
The FileReader type represents an asynchronous file reading mechanism. You can think of FileReader as similar to XMLHttpRequest, except that it is used to read files from the file system instead of reading data from the server. The FileReader type provides several methods for reading file data.
readAsText(file,encoding);//Read plain text content from the file and save it in the result attribute
readAsDataURL(file);//Read the file and save the data URI of the content in the result attribute
readAsBinaryString(file);/ /Read the file and save the binary data of each character in the result attribute
readAsArrayBuffer(file); //Read the file and save the file content in the result attribute in the form of ArrayBuffer
A synchronous version of the FileReader type.
In some cases, you may need to read part of the file instead of the entire file. For this purpose, the File object provides a method called slice(). The slice() method receives two parameters: the starting byte and the number of bytes in the Yaodu area. This method returns an instance of Blob, which is actually a superclass of File.
Blob represents a binary large object, which is JavaScript’s encapsulation type for unmodifiable binary data. Arrays containing strings, ArrayBuffers, ArrayBufferViews, and even other blobs can be used to create blobs. The Blob constructor can receive an options parameter and specify the MIME type in it.
Streams API was born to solve a simple but basic problem: How does a web application consume ordered small blocks of information instead of large blocks of information? There are two main application scenarios for this capability.
The Streams API defines three streams:
Readable stream: A stream that can read data blocks through a public interface. Data enters the stream internally from the underlying source and is then processed by the consumer.
Writable stream: A stream to which blocks of data can be written via some public interface. The producer (consumer) writes data to the stream, and the data is transferred internally to the underlying data slot (sink).
Conversion stream: It consists of two streams, the writable stream is used to receive data, and the readable stream is used to output data. These two stream quality checks are transformers that can inspect and modify stream content as needed.
The Web Cryptography API describes a set of cryptography tools that standardizes how JavaScript implements encryption in a secure and conventional manner. These tools include generating, using, and applying cryptographic key pairs, encrypting and decrypting information, and reliably generating random numbers.
Many people use Math.random()
when they need to generate random numbers. This method is implemented in the browser as a pseudo-random number generator (PRNG, PseudoRandom Number Generator). The so-called pseudo refers to the process of generating values that is not truly random. The values generated by PRNG only simulate random characteristics. The browser's PRNG does not use a true random source, but only applies a fixed algorithm to an internal state. Each time Math.random()
is called, this internal state is modified by an algorithm, and the result is converted into a new random number. For example, the V8 engine uses an algorithm called xorshift128+
to perform this modification.
Since the algorithm itself is fixed and its input is only the previous state, the random number sequence is also determined. xorshift128+
uses 128-bit internal state, and the algorithm is designed so that any initial state generates 2 128 -1 pseudo-random values before repeating itself. This kind of loop is called a permutation loop, and the length of this loop is called a period. It is obvious that if the attacker knows the internal state of the PRNG, he can predict the subsequently generated pseudo-random values. If the developer inadvertently uses PRNG to generate a private key for encryption, the attacker can use this feature of PRNG to calculate the private key.
Pseudo-random number generators are mainly used to quickly calculate seemingly random numbers, but are not suitable for encryption algorithms. To solve this problem, cryptographically secure pseudo-random number generator (CSPRNG, Cryptographically Secure PseudoRandom Number Generator), additionally Adding an entropy as input, such as testing hardware time or other system characteristics with unpredictable behavior, although not as fast as PRNG, the generated value is more difficult to predict and can be used for encryption.
The Web Cryptography API introduces CSPRNG, which can be accessed on the global Crypto
object through crypto.getRandomValues()
. Unlike Math.random()
which returns a floating point number between 0 and 1, getRandomValues()
writes random values into the stereotyped array passed to it as a parameter. The class of the stereotyped array does not matter because the underlying buffer will be filled with random bits.