Nodejs ngoại lệ chưa được phát hiện

Có một cú pháp đặc biệt để làm việc với các lời hứa một cách thoải mái hơn, được gọi là “async/await”. Nó dễ hiểu và dễ sử dụng một cách đáng ngạc nhiên

Chức năng không đồng bộ

Hãy bắt đầu với từ khóa

async function f() {
  return 1;
}

f().then(alert); // 1
7. Nó có thể được đặt trước một chức năng, như thế này

async function f() {
  return 1;
}

Từ "không đồng bộ" trước một chức năng có nghĩa là một điều đơn giản. một hàm luôn trả về một lời hứa. Các giá trị khác được tự động bao bọc trong một lời hứa đã giải quyết

Chẳng hạn, hàm này trả về một lời hứa đã giải quyết với kết quả là

async function f() {
  return 1;
}

f().then(alert); // 1
8;

async function f() {
  return 1;
}

f().then(alert); // 1

…Chúng ta có thể trả lại một lời hứa một cách rõ ràng, điều này sẽ giống nhau

async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1

Vì vậy,

async function f() {
  return 1;
}

f().then(alert); // 1
7 đảm bảo rằng hàm trả về một lời hứa và bao bọc những điều không hứa hẹn trong đó. Đủ đơn giản, phải không? . Có một từ khóa khác,
async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1
0, chỉ hoạt động bên trong các hàm của
async function f() {
  return 1;
}

f().then(alert); // 1
7 và nó khá thú vị

Chờ đợi

cú pháp

________số 8

Từ khóa

async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1
0 khiến JavaScript đợi cho đến khi lời hứa đó hoàn thành và trả về kết quả của nó

Đây là một ví dụ với một lời hứa sẽ giải quyết trong 1 giây

async function f() {
  return 1;
}
0

Việc thực thi chức năng "tạm dừng" tại dòng

async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1
3 và tiếp tục khi lời hứa ổn định, với
async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1
4 trở thành kết quả của nó. Vì vậy, đoạn mã trên hiển thị “xong. ” trong một giây

Hãy nhấn mạnh.

async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1
0 thực sự tạm dừng việc thực thi chức năng cho đến khi lời hứa được giải quyết, sau đó tiếp tục lại với kết quả lời hứa. Điều đó không tốn bất kỳ tài nguyên CPU nào, bởi vì công cụ JavaScript có thể thực hiện các công việc khác trong thời gian chờ đợi. thực thi các tập lệnh khác, xử lý các sự kiện, v.v.

Nó chỉ là một cú pháp tao nhã hơn để nhận được kết quả hứa hẹn hơn là

async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1
6. Và, nó dễ dàng hơn để đọc và viết

Không thể sử dụng

async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1
0 trong các chức năng thông thường

Nếu chúng tôi cố gắng sử dụng

async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1
0 trong một chức năng không đồng bộ, sẽ có lỗi cú pháp

async function f() {
  return 1;
}
7

Chúng ta có thể gặp lỗi này nếu quên đặt

async function f() {
  return 1;
}

f().then(alert); // 1
7 trước một hàm. Như đã nêu trước đó,
async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1
0 chỉ hoạt động bên trong hàm
async function f() {
  return 1;
}

f().then(alert); // 1
7

Hãy lấy ví dụ về

// works only inside async functions
let value = await promise;
2 từ chương Promises chain và viết lại nó bằng cách sử dụng
// works only inside async functions
let value = await promise;
3

  1. Chúng tôi sẽ cần thay thế các cuộc gọi
    // works only inside async functions
    let value = await promise;
    4 bằng
    async function f() {
      return Promise.resolve(1);
    }
    
    f().then(alert); // 1
    0
  2. Ngoài ra, chúng ta nên tạo hàm
    async function f() {
      return 1;
    }
    
    f().then(alert); // 1
    7 để chúng hoạt động

async function f() {
  return 1;
}

f().then(alert); // 1
6

Khá sạch sẽ và dễ đọc, phải không?

Các trình duyệt hiện đại cho phép

async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1
0 cấp cao nhất trong các mô-đun

Trong các trình duyệt hiện đại,

async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1
0 ở cấp cao nhất chỉ hoạt động tốt khi chúng tôi ở trong một mô-đun. Chúng tôi sẽ đề cập đến các mô-đun trong bài viết Mô-đun, giới thiệu

Ví dụ

async function f() {
  return 1;
}

f().then(alert); // 1
9

Nếu chúng tôi không sử dụng các mô-đun hoặc các trình duyệt cũ hơn phải được hỗ trợ, thì sẽ có một công thức chung. gói vào một chức năng không đồng bộ ẩn danh

Như thế này

async function f() {
  return 1;
}

f().then(alert); // 1
0

async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1
0 chấp nhận “thenables”

Giống như

async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1
6,
async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1
0 cho phép chúng ta sử dụng các đối tượng có thể gọi được (những đối tượng có phương thức
async function f() {
  return 1;
}
02 có thể gọi được). Ý tưởng là một đối tượng của bên thứ ba có thể không phải là một lời hứa, nhưng tương thích với lời hứa. nếu nó hỗ trợ
// works only inside async functions
let value = await promise;
4, thế là đủ để sử dụng nó với
async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1
0

Đây là một lớp

async function f() {
  return 1;
}
05 demo;

async function f() {
  return 1;
}

f().then(alert); // 1
9

Nếu

async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1
0 nhận một đối tượng không hứa hẹn với
// works only inside async functions
let value = await promise;
4, thì nó gọi phương thức đó cung cấp các hàm tích hợp sẵn
async function f() {
  return 1;
}
09 và
async function f() {
  return 1;
}
70 làm đối số (giống như đối với trình thực thi
async function f() {
  return 1;
}
71 thông thường). Sau đó,
async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1
0 đợi cho đến khi một trong số chúng được gọi (trong ví dụ trên, nó xảy ra ở dòng
async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1
3) rồi tiếp tục với kết quả

Phương thức lớp không đồng bộ

Để khai báo một phương thức lớp không đồng bộ, chỉ cần thêm vào trước nó bằng

async function f() {
  return 1;
}

f().then(alert); // 1
7

async function f() {
  return 1;
}

f().then(alert); // 1
0

Ý nghĩa là như nhau. nó đảm bảo rằng giá trị được trả về là một lời hứa và cho phép

async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1
0

xử lý lỗi

Nếu một lời hứa giải quyết bình thường, thì

async function f() {
  return 1;
}
76 trả về kết quả. Nhưng trong trường hợp bị từ chối, nó sẽ báo lỗi, giống như có một câu lệnh
async function f() {
  return 1;
}
77 tại dòng đó

mã này

async function f() {
  return 1;
}

f().then(alert); // 1
1

…cũng giống như thế này

async function f() {
  return 1;
}

f().then(alert); // 1
2

Trong các tình huống thực tế, lời hứa có thể mất một thời gian trước khi từ chối. Trong trường hợp đó sẽ có độ trễ trước khi

async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1
0 đưa ra lỗi

Chúng tôi có thể phát hiện lỗi đó bằng cách sử dụng

async function f() {
  return 1;
}
79, giống như cách sử dụng
async function f() {
  return 1;
}
77 thông thường

async function f() {
  return 1;
}

f().then(alert); // 1
3

Trong trường hợp có lỗi, điều khiển sẽ nhảy đến khối

async function f() {
  return 1;
}

f().then(alert); // 1
61. Chúng tôi cũng có thể bọc nhiều dòng

async function f() {
  return 1;
}

f().then(alert); // 1
4

Nếu chúng ta không có

async function f() {
  return 1;
}
79, thì lời hứa được tạo bởi lệnh gọi hàm async
async function f() {
  return 1;
}

f().then(alert); // 1
63 sẽ bị từ chối. Chúng ta có thể nối thêm
async function f() {
  return 1;
}

f().then(alert); // 1
64 để xử lý nó

async function f() {
  return 1;
}

f().then(alert); // 1
5

Nếu chúng tôi quên thêm

async function f() {
  return 1;
}

f().then(alert); // 1
64 vào đó, thì chúng tôi sẽ gặp lỗi lời hứa chưa được xử lý (có thể xem được trong bảng điều khiển). Chúng ta có thể phát hiện những lỗi như vậy bằng cách sử dụng trình xử lý sự kiện toàn cầu
async function f() {
  return 1;
}

f().then(alert); // 1
66 như được mô tả trong chương Xử lý lỗi bằng lời hứa

// works only inside async functions
let value = await promise;
3 và
async function f() {
  return 1;
}

f().then(alert); // 1
68

Khi chúng tôi sử dụng

// works only inside async functions
let value = await promise;
3, chúng tôi hiếm khi cần đến
// works only inside async functions
let value = await promise;
4, vì
async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1
0 xử lý việc chờ đợi cho chúng tôi. Và chúng ta có thể sử dụng
async function f() {
  return 1;
}
79 thông thường thay vì
async function f() {
  return 1;
}

f().then(alert); // 1
64. Điều đó thường (nhưng không phải luôn luôn) thuận tiện hơn

Nhưng ở cấp cao nhất của mã, khi chúng tôi ở bên ngoài bất kỳ hàm

async function f() {
  return 1;
}

f().then(alert); // 1
7 nào, chúng tôi không thể sử dụng
async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1
0 về mặt cú pháp, do đó, thông thường là thêm
async function f() {
  return 1;
}

f().then(alert); // 1
96 để xử lý kết quả cuối cùng hoặc lỗi rơi xuống, như trong dòng

// works only inside async functions
let value = await promise;
3 hoạt động tốt với
async function f() {
  return 1;
}

f().then(alert); // 1
99

Khi chúng ta cần đợi nhiều lời hứa, chúng ta có thể gói chúng trong

async function f() {
  return 1;
}

f().then(alert); // 1
99 và sau đó là
async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1
0

async function f() {
  return 1;
}

f().then(alert); // 1
6

Trong trường hợp có lỗi, nó sẽ lan truyền như bình thường, từ fail promise thành

async function f() {
  return 1;
}

f().then(alert); // 1
99, rồi trở thành một ngoại lệ mà chúng ta có thể bắt gặp bằng cách sử dụng
async function f() {
  return 1;
}
79 xung quanh cuộc gọi

Bản tóm tắt

Từ khóa

async function f() {
  return 1;
}

f().then(alert); // 1
7 trước hàm có hai tác dụng

  1. Làm cho nó luôn trả lại một lời hứa
  2. Cho phép sử dụng
    async function f() {
      return Promise.resolve(1);
    }
    
    f().then(alert); // 1
    0 trong đó

Từ khóa

async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1
0 trước một lời hứa làm cho JavaScript đợi cho đến khi lời hứa đó ổn định, rồi sau đó

  1. Nếu đó là lỗi, một ngoại lệ sẽ được tạo - giống như khi
    async function f() {
      return 1;
    }
    
    f().then(alert); // 1
    07 được gọi tại chính nơi đó
  2. Ngược lại, nó trả về kết quả

Họ cùng nhau cung cấp một khuôn khổ tuyệt vời để viết mã không đồng bộ, dễ đọc và viết

Với

// works only inside async functions
let value = await promise;
3, hiếm khi chúng ta cần viết
async function f() {
  return 1;
}

f().then(alert); // 1
68, nhưng chúng ta vẫn không nên quên rằng chúng dựa trên những lời hứa, bởi vì đôi khi (e. g. trong phạm vi ngoài cùng), chúng ta phải sử dụng các phương pháp này. Ngoài ra,
async function f() {
  return 1;
}

f().then(alert); // 1
99 thật tuyệt khi chúng tôi đang chờ đợi nhiều nhiệm vụ cùng một lúc