在前面我們簡單的介紹了一些 Futures 的基本知識的例子中速址,我們出現(xiàn)了 combinator 的概念尺上,也就是 and_then
這些。Combinator 能將多個 Future 串聯(lián)組合起來,依次執(zhí)行調(diào)動匠楚,最終得到結(jié)果捷沸。
在 futures 庫里面摊沉,已經(jīng)提供了一些基本的 Future,后面痒给,我們會結(jié)合這些 concrete 的 Future说墨,來具體說明一下 combinator。
Leaf Future
在 futures 里面苍柏,有一種 leaf future 尼斧,也就是 FutureResult,它只要調(diào)用 poll
就能夠及時的返回值试吁,不需要額外的等待棺棵。后續(xù)很多的例子我們都會通過這種 leaf future 來完成。
使用 leaf future 也是非常簡單的熄捍,我們可以通過 ok
, err
以及 result
來完成:
let f = ok::<u32, u32>(1);
assert_eq!(f.wait().unwrap(), 1);
let f = err::<u32, u32>(2);
assert_eq!(f.wait().unwrap_err(), 2);
let f = result::<u32, u32>(Ok(3));
assert_eq!(f.wait().unwrap(), 3);
let f = result::<u32, u32>(Err(4));
assert_eq!(f.wait().unwrap_err(), 4);
Empty Future
不同于上面的 leaf future烛恤,我們還可以創(chuàng)建一種 empty future,它在任何 poll
的時候余耽,都會返回 NotReady
缚柏。
let mut f1 = empty::<u32, u32>();
assert_eq!(f1.poll(), Ok(Async::NotReady));
Map / MapErr Future
我們可以使用 map
或者 map_err
將一個 Future 轉(zhuǎn)為另一個 Future,譬如:
let f = ok::<u32, u32>(1);
let f2 = f.map(|x| x + 1);
assert_eq!(f2.wait().unwrap(), 2);
let f = err::<u32, u32>(2);
let f2 = f.map_err(|x| x + 2);
assert_eq!(f2.wait().unwrap_err(), 4);
Then / AndThen / OrElse Future
我們也可以使用 then
/ and_then
/ or_else
來將當(dāng)前 Future 完成的值傳遞給下一個 Future 處理:
let f = ok::<u32, u32>(1);
let f2 = f.then(|x| x.map(|y| y + 1));
assert_eq!(f2.wait().unwrap(), 2);
let f = err::<u32, u32>(2);
let f2 = f.then(|x| x.map_err(|y| y + 2));
assert_eq!(f2.wait().unwrap_err(), 4);
let f = ok::<u32, u32>(1);
let f2 = f.and_then(|x| Ok(x + 1));
assert_eq!(f2.wait().unwrap(), 2);
let f = err::<u32, u32>(2);
let f2 = f.or_else(|x| Err(x + 2));
assert_eq!(f2.wait().unwrap_err(), 4);
Select / Join Future
我們可以使用 select
/ join
來等待一個或者所有 Future 完成:
let f1 = ok::<u32, u32>(1);
let f2 = ok::<u32, u32>(2);
let _ = f1.select(f2).map(|(x, y)| {
assert_eq!(x, 1);
assert_eq!(y.wait().unwrap(), 2);
});
let f1 = ok::<u32, u32>(1);
let f2 = ok::<u32, u32>(2);
let _ = f1.join(f2).map(|(x, y)| {
assert_eq!(x, 1);
assert_eq!(y, 2);
});
Flatten Future
也可以使用 flatten
來得到最后一個 Future 的值:
let f1 = ok::<u32, u32>(1);
let f2 = ok::<_, u32>(f1);
assert_eq!(f2.flatten().wait().unwrap(), 1);
Fuse Future
通常一個 Future 完成之后碟贾,再次去 poll
會 panic 出錯币喧,為了防止這樣的情況出現(xiàn)轨域,我們可以使用 fuse
,這樣當(dāng) Future 已經(jīng)完成之后杀餐,后面任何 poll
都會返回 NotReady
:
let mut f1 = ok::<u32, u32>(1);
assert_eq!(f1.poll(), Ok(Async::Ready(1)));
let mut f1 = ok::<u32, u32>(1).fuse();
assert_eq!(f1.poll(), Ok(Async::Ready(1)));
assert_eq!(f1.poll(), Ok(Async::NotReady));
Channel
futures 現(xiàn)在提供兩種 channel干发,one-shot 以及 MPSC。one-shot 主要用于兩個線程之間交互的情況史翘,而 MPSC 則是可以多個線程發(fā)送數(shù)據(jù)枉长,一個線程接受處理。
一個 one-shot 的簡單例子:
let (tx, rx) = oneshot::channel::<u32>();
thread::spawn(move || {
tx.complete(1);
});
rx.map(|x| {
assert_eq!(x, 1);
})
.wait()
.unwrap();
一個 MPSC 的簡單例子:
let (tx, rx) = mpsc::channel::<u32>(1);
let tx1 = tx.clone();
thread::spawn(move || {
tx1.send(1).wait().unwrap();
});
let tx2 = tx.clone();
thread::spawn(move || {
tx2.send(2).wait().unwrap();
});
drop(tx);
let mut w = rx.wait();
assert_eq!(w.next().unwrap(), Ok(1));
assert_eq!(w.next().unwrap(), Ok(2));
assert!(w.next().is_none());
小結(jié)
這里恶座,我們簡單介紹了 futures 庫提供的一些基本 future搀暑,combinator,以及他們的使用方法跨琳。 可以看到自点,使用都是非常簡單的。這里脉让,我們并沒有詳細(xì)的說明 Stream桂敛,但也沒有特別大的差別。另外溅潜,futures 庫還有一個關(guān)鍵的 task 概念术唬,這個我們后續(xù)在說明。