用rust实现一下std::promise
时间: 2024-05-15 08:19:32 浏览: 190
采用Symbol和process.nextTick实现Promise
由于Rust中没有类似于C++的std::promise的预定义类型,我们需要自己实现一个类似的功能。下面是一个简单的实现,它包含一个Future和一个Resolver:
```rust
use std::cell::RefCell;
use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use std::sync::Mutex;
use std::task::{Context, Poll, Waker};
pub struct Promise<T> {
future: Arc<Mutex<Option<Box<dyn Future<Output = T> + Send>>>>,
resolver: Arc<Mutex<Option<Resolver<T>>>>,
}
impl<T> Promise<T> {
pub fn new() -> Self {
let future = Arc::new(Mutex::new(None));
let resolver = Arc::new(Mutex::new(None));
Promise { future, resolver }
}
pub fn get_future(&self) -> impl Future<Output = T> + Send {
let future = self.future.clone();
let waker = Arc::new(RefCell::new(None));
let resolver = self.resolver.clone();
Box::new(async move {
let mut future = future.lock().unwrap();
*future = Some(Box::new(FutureImpl {
waker: waker.clone(),
resolver: resolver.clone(),
}));
future.as_mut().unwrap().await
})
}
pub fn set_value(&self, value: T) {
let resolver = self.resolver.lock().unwrap();
if let Some(resolver) = resolver.as_ref() {
resolver.set_value(value);
}
}
pub fn set_error(&self, error: Box<dyn std::error::Error + Send>) {
let resolver = self.resolver.lock().unwrap();
if let Some(resolver) = resolver.as_ref() {
resolver.set_error(error);
}
}
}
struct FutureImpl<T> {
waker: Arc<RefCell<Option<Waker>>>,
resolver: Arc<Mutex<Option<Resolver<T>>>>,
}
impl<T> Future for FutureImpl<T> {
type Output = T;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let mut resolver = self.resolver.lock().unwrap();
if let Some(resolver) = resolver.as_mut() {
match resolver.poll(cx) {
Poll::Ready(output) => Poll::Ready(output),
Poll::Pending => {
*self.waker.borrow_mut() = Some(cx.waker().clone());
Poll::Pending
}
}
} else {
panic!("Resolver is missing");
}
}
}
struct Resolver<T> {
waker: Option<Waker>,
value: Option<T>,
error: Option<Box<dyn std::error::Error + Send>>,
}
impl<T> Resolver<T> {
pub fn set_value(&self, value: T) {
if let Some(waker) = self.waker.as_ref() {
waker.wake_by_ref();
}
*self.value.as_ref().unwrap() = value;
}
pub fn set_error(&self, error: Box<dyn std::error::Error + Send>) {
if let Some(waker) = self.waker.as_ref() {
waker.wake_by_ref();
}
*self.error.as_ref().unwrap() = error;
}
pub fn poll(&mut self, cx: &mut Context<'_>) -> Poll<T> {
if let Some(value) = self.value.take() {
Poll::Ready(value)
} else if let Some(error) = self.error.take() {
Poll::Ready(Err(error))
} else {
self.waker = Some(cx.waker().clone());
Poll::Pending
}
}
}
```
这个实现包含一个Promise结构体,它有一个get_future方法来获取一个Future,set_value和set_error方法来设置结果。FutureImpl结构体是Future的实际实现,它存储了一个Waker和一个Resolver。Resolver结构体存储了一个Waker、一个值和一个错误。当Future被唤醒时,它会检查Resolver是否有一个值或错误,如果有,它会返回结果,否则它将存储Waker并等待结果。当Promise被设置时,Resolver将唤醒Future并存储结果。
阅读全文