返回

异步与等待 (4):固定

见解分享

在本文中,我们已经多次遇到术语“固定”。现在,让我们深入探讨什么是固定以及为什么它在异步编程中至关重要。

正如前面解释的那样,状态机的转换将每个暂停点的局部变量存储在一个结构体中。对于像示例函数这样的简单示例,这是非常直观的,不会造成任何问题。但是,当变量开始相互引用时,情况就会变得复杂。

Consider the following code:

async function example() {
  const a = 1;
  const b = 2;

  const c = await Promise.resolve(3);

  a += c; // 'a' is still available here
  b += c; // 'b' is still available here

  return a + b;
}

In this code, the variables a and b are declared before the await expression. This means that they are available in the scope of the entire function, even after the await expression has been executed. However, this is not always the case.

Consider the following modified code:

async function example() {
  let a = 1;
  const b = 2;

  const c = await Promise.resolve(3);

  a += c; // 'a' is still available here
  b += c; // 'b' is still available here

  return a + b;
}

In this code, the variable a is declared using the let keyword. This means that it is only available in the scope of the block in which it is declared. After the await expression is executed, the block in which a is declared is exited, and a is no longer available.

This is where pinning comes into play. Pinning is a technique that allows us to keep variables available even after the block in which they are declared has been exited. This is done by storing the variables in a special location in memory.

There are two main types of pinning:

  • Implicit pinning: This type of pinning occurs automatically when a variable is declared using the const keyword.
  • Explicit pinning: This type of pinning occurs when we manually store a variable in a special location in memory using the pin keyword.

In the first example, the variables a and b are implicitly pinned because they are declared using the const keyword. This means that they are available in the scope of the entire function, even after the await expression has been executed.

In the second example, the variable a is not implicitly pinned because it is declared using the let keyword. This means that it is only available in the scope of the block in which it is declared. However, we can explicitly pin a using the pin keyword, as follows:

async function example() {
  let a = 1;
  const b = 2;

  const c = await Promise.resolve(3);

  pin(a); // Explicitly pin 'a'

  a += c; // 'a' is still available here
  b += c; // 'b' is still available here

  return a + b;
}

By explicitly pinning a, we ensure that it remains available even after the block in which it is declared has been exited.

Pinning is a powerful technique that can be used to improve the performance and maintainability of asynchronous code. By carefully pinning variables, we can avoid the need to re-fetch them from memory, which can lead to significant performance improvements. Additionally, pinning can help to make code more readable and maintainable by ensuring that variables are always available when they are needed.