Lưu đối số khối giá trị vào bộ nhớ đệm

Đôi khi, trình tạo mã khối cần tham chiếu nhiều lần mã của khối bên trong.

Ví dụ: nếu có một khối lấy phần tử cuối cùng của danh sách, bạn cần truy cập vào mã danh sách nhiều lần:

// Incorrect block-code generator.
javascriptGenerator.forBlock['last_element'] = function(block, generator) {
  const listCode = generator.valueToCode(block, 'LIST', Order.MEMBER);

  // listCode gets referenced twice.
  const code = `${listCode}[${listCode}.length - 1]`;

  return [code, Order.MEMBER];
}

Tuy nhiên, điều này có thể gây ra sự cố nếu giá trị kết quả của mã của khối bên trong không nhất quán hoặc có tác dụng phụ. Ví dụ: nếu mã bên trong thực sự là một lệnh gọi hàm, thì mã cụ thể này có thể kết thúc bằng một điều kiện nằm ngoài phạm vi:

randomList()[randomList().length - 1]

Khi sử dụng các hàm hiệu dụng, bạn có thể đảm bảo mã của các khối bên trong chỉ được đánh giá một lần.

Hàm hiệu dụng

Hàm hiệu dụng là một hàm do nhà phát triển xác định, có trong chuỗi mã được tạo. Bạn có thể sử dụng chúng để đảm bảo rằng mã khối bên trong chỉ được đánh giá một lần, sau đó giá trị có thể được tham chiếu nhiều lần.

import {javascriptGenerator, Order} from 'blockly/javascript';

// Correct block-code generator.
javascriptGenerator.forBlock['last_element'] = function(block, generator) {
  const listCode = generator.valueToCode(block, 'LIST', Order.NONE);
  const functionName = generator.provideFunction_(
      'list_lastElement',
      [
        `function ${generator.FUNCTION_NAME_PLACEHOLDER_}(list) {`,
        `  return list[list.length - 1];`,
        `}`
      ]
  );

  // listCode only gets evaluated once.
  const code = `${functionName}(${listCode})`;
  return [code, Order.FUNCTION_CALL];
}

Cung cấp hàm

Bạn có thể xác định các hàm hiệu dụng bên trong trình tạo mã khối bằng provideFunction_. Hàm này sẽ lấy tên bạn muốn cho hàm hiệu dụng và một mảng chuỗi mã xác định chức năng của hàm. Hàm này sẽ trả về tên kết quả của hàm hiệu dụng, sau khi (có thể) sửa đổi hàm đó để không xung đột với các hàm do người dùng xác định.

provideFunction_ cũng loại bỏ các định nghĩa hàm tiện ích để mỗi hàm tiện ích chỉ tồn tại một lần, ngay cả khi loại khối xác định hàm đó tồn tại nhiều lần.

Cập nhật mức độ ưu tiên

Khi xác định một hàm hiệu dụng, bạn cũng nên cập nhật mức độ ưu tiên (xác định cách chèn dấu ngoặc đơn) được đưa vào trình tạo mã khối.

Mức độ ưu tiên luôn dựa trên chuỗi mã do trình tạo mã khối trả về. Phần mềm này không quan tâm đến các toán tử bên trong các hàm hiệu dụng. Vì vậy, trong ví dụ trước, lệnh gọi valueToCode đã được thay đổi thành Order.NONE và bộ dữ liệu trả về đã được thay đổi thành Order.FUNCTION_CALL.