Async và Await lần đầu tiên được giới thiệu trong C#, để cấu trúc mã không chặn theo kiểu tương tự như bạn sẽ viết mã chặn. Những từ khóa này sau đó đã được xuất sang một số ngôn ngữ lập trình vì nó tạo điều kiện thuận lợi cho việc quản lý mã không đồng bộ
Thật vậy, có nhiều cách khác để viết mã không đồng bộ, nếu bạn biết Javascript/Nodejs thì có lẽ bạn đã sử dụng các cuộc gọi lại
fs = require['fs'];
fs.writeFile['hello.txt', 'call back exemple in nodejs', [err] => {
if [err] return console.log[err];
console.log['file writen'];
}];
Hàm gọi lại được truyền ở vị trí thứ hai ở đây sẽ được gọi khi sự kiện đang diễn ra
Sau đó, cũng có các Lời hứa cho phép quản lý tốt hơn các cuộc gọi không đồng bộ bằng các từ biểu cảm
import axios from 'axios'let data;
axios.get["//jsonplaceholder.typicode.com/posts"]
.then[resp => {
data = resp.data //do data processing as data is actually available
}]
.catch[err => { console.log[err] }]console.log[data] // undefined even if the instruction is after the API call
Một trong những vấn đề với các kỹ thuật này là chúng ta thoát khỏi luồng đọc mã theo chiều ngang, điều này ảnh hưởng đến khả năng đọc. Dù sao đi nữa, hãy quay lại cách nó tác động đến bạn với tư cách là người dùng Python
Sự cố với mã IO tiêu chuẩn trong Python
Mã IO là một hướng dẫn sẽ gọi một dịch vụ bên ngoài. Ví dụ, đây có thể là một yêu cầu HTTP hoặc một cuộc gọi đến cơ sở dữ liệu. Vấn đề với mã python tiêu chuẩn là mã của bạn nếu nó chỉ gọi các dịch vụ này, sẽ phải đợi cho đến khi các dịch vụ này phản hồi trước khi chuyển sang hướng dẫn tiếp theo
import requestsdata = [requests
.get["//jsonplaceholder.typicode.com/posts"]
.json[]
] # blocking code block, python waiting doing nothingfor d in data: # executed once the API has return
print[d]
Trong ví dụ trên không khó chịu lắm vì chỉ có một lệnh gọi đến dịch vụ bên ngoài nhưng hãy lấy mã bên dưới
def fetch_comments[]:
data = []
for i in range[1, 500]:
url = f"//jsonplaceholder.typicode.com/comments/{i}"
resp = requests.get[url].json[]
data.append[resp]fetch_comments[]
Mã này mất 126. 95 giây để hoàn thành trên máy của tôi. Do đó, chúng ta có thể thấy rằng nó không tối ưu. Chúng ta cần giới thiệu song song, tôi. e. thực hiện nhiều yêu cầu cùng một lúc
cách cổ điển. chủ đề
Trước khi xuất hiện asyncio trong Python, để xử lý loại vấn đề này, bạn phải sử dụng các luồng. Một luồng là một thành phần của một quy trình có thể được quản lý đồng thời. Tuy nhiên, Python có khóa trình thông dịch toàn cầu giới hạn việc sử dụng luồng đối với các lệnh không sử dụng mã được giải thích. Đây không phải là trường hợp ở đây vì chúng tôi sử dụng một dịch vụ bên ngoài. Không cần phải quảng cáo thêm, đây là phiên bản chủ đề của mã gọi API
Phiên bản chủ đề của nguồn lệnh gọi API. tác giảCó thể thấy, phiên bản mã luồng đòi hỏi nhiều nỗ lực hơn phiên bản đồng bộ. Thật vậy, chúng ta phải quản lý một hàng đợi cho phép các luồng chọn các URL khác nhau để xử lý
Mặt khác, trên máy của tôi, việc thực thi mã này với 5 luồng được sinh ra chỉ mất 7. 05 giây để hoàn thành, giảm 94% so với phiên bản đồng bộ. Nhưng nếu tôi nói với bạn rằng chúng ta có thể làm tốt hơn
cách hiện đại. mã không đồng bộ
Hãy xem cách thực hiện lệnh gọi API bằng mã không đồng bộ
Phiên bản không đồng bộ của nguồn lệnh gọi API. tác giảỞ đây cũng vậy, có nhiều nỗ lực hơn để sản xuất để có được kết quả tương tự như phiên bản đồng bộ và ít nhất là nhiều nỗ lực như phiên bản có luồng, vậy nó có xứng đáng với chi phí không? . 4880 giây để hoàn thành, bạn cho tôi biết
Vậy tại sao phiên bản không đồng bộ lại hoạt động tốt như vậy so với các luồng?
Sự kết luận
Bài viết này nhằm mục đích chỉ cho bạn cách mã không đồng bộ có thể cải thiện hiệu suất của một số tác vụ của bạn. Có rất nhiều hướng dẫn trên web để tìm hiểu cách sử dụng mô hình mới này trong python
Mặc dù async đã được hỗ trợ trong Python trong một vài năm, nhưng bạn phải nhớ rằng không phải tất cả các thư viện cũ đều hỗ trợ async vì nó ngụ ý phải viết lại mã. Ví dụ: bạn hẳn đã nhận thấy rằng tôi không thể sử dụng các yêu cầu trong ví dụ không đồng bộ nhưng aiohttp phiên bản không đồng bộ tương đương
Nếu bạn bị thuyết phục và muốn chuyển sang async, kho lưu trữ aio-libs cung cấp một bộ thư viện dựa trên asyncio và họ có thể có một thư viện phù hợp với nhu cầu của bạn