Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Stream

Iterator cho một chuỗi giá trị lấy được ngay lập tức, từng bước; Stream là phiên bản bất đồng bộ của ý tưởng đó — một chuỗi giá trị mà mỗi bước lấy tiếp theo có thể phải chờ (một gói tin mạng, một dòng dữ liệu đọc dần từ đĩa), tương ứng poll_next trả Poll::Pending khi phần tử kế tiếp chưa sẵn sàng, Poll::Ready(Some(gia_tri)) khi có, Poll::Ready(None) khi hết:

trait Stream {
    type Item;
    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>;
}

Trait Stream chưa ổn định trong thư viện chuẩn tại thời điểm viết sách này — dùng qua crate ngoài (futures::stream::Stream, hoặc tương đương do runtime cung cấp), tương tự tình huống Future tự chạy được cần một executor ngoài std.

Duyệt qua Stream

Runtime/crate cung cấp method tiện dụng để duyệt Stream gần giống for với Iterator, chỉ khác mỗi bước cần .await:

use futures::stream::{self, StreamExt};

async fn vi_du() {
    let mut stream = stream::iter(vec![1, 2, 3]);

    while let Some(gia_tri) = stream.next().await {
        println!("{gia_tri}");
    }
}

Kết hợp adaptor như Iterator

Stream hỗ trợ các adaptor quen thuộc từ Iterator (map, filter, take, …) — vẫn giữ nguyên tính lười: một chuỗi .map(...).filter(...) trên Stream không tự chạy gì cho tới khi có thứ gì đó thật sự .await từng phần tử ra, y hệt tinh thần lười của Iterator đã học ở chương Closure và Iterator, chỉ khác mỗi bước giờ có thể tạm dừng chờ thay vì luôn có sẵn ngay:

use futures::stream::{self, StreamExt};

async fn vi_du() {
    let tong: i32 = stream::iter(vec![1, 2, 3, 4])
        .map(|x| x * 2)
        .filter(|x| {
            let giu_lai = *x > 2;
            async move { giu_lai }
        })
        .fold(0, |tong, x| async move { tong + x })
        .await;

    println!("{tong}");
}

Cùng một tư duy xử lý dữ liệu theo chuỗi phép biến đổi khai báo được (declarative) như Iterator, mở rộng sang ngữ cảnh mỗi bước có thể cần chờ — không phải một mô hình tư duy hoàn toàn mới.