如何在期货集中获得第一个未来的结果?

发布于 2025-02-11 19:48:02 字数 1261 浏览 1 评论 0原文

我有一堆async_std :: udpsocket,并希望将它们全部驱动到第一个人完成,然后从其相应的u8 buffer中获取结果。

我尝试过

// build sockets and buffers
let sockets = Vec::new();
let buffers = HashMap::new();
for addr in ["127.0.0.1:4000", "10.0.0.1:8080", "192.168.0.1:9000"] {
    let socket = UdpSocket::bind(addr.parse().unwrap()).await?;
    let buf = [0u8; 1500];
    sockets.push(socket);
    buffers.insert(socket.peer_addr()?, buf);
}

// create an iterator of tasks reading from each socket
let socket_tasks = sockets.into_iter().map(|socket| {
    let socket_addr = socket.peer_addr().unwrap();
    let buf = buffers.get_mut(&socket_addr).unwrap();
    socket
        .recv_from(buf)
        .and_then(|_| async move { Ok(socket_addr) })
});

// wait for the first socket to return a value (DOESN'T WORK)
let buffer = try_join_all(socket_tasks)
    .and_then(|socket_addr| async { Ok(buffers.get(&socket_addr)) })
    .await

,但是这不起作用,因为期货:: future :: try_join_all drives 全部所有期货都可以完成,并返回vec&lt;(socketAddr)&gt; < /代码>。我想在A single Future完成并仅获得socketAddr - 类似于select!select!但在集合上获得的东西。

怎么办?

I have a bunch of async_std::UdpSocket and want to drive them all until the first one completes, then get the result from its corresponding u8 buffer.

I've tried

// build sockets and buffers
let sockets = Vec::new();
let buffers = HashMap::new();
for addr in ["127.0.0.1:4000", "10.0.0.1:8080", "192.168.0.1:9000"] {
    let socket = UdpSocket::bind(addr.parse().unwrap()).await?;
    let buf = [0u8; 1500];
    sockets.push(socket);
    buffers.insert(socket.peer_addr()?, buf);
}

// create an iterator of tasks reading from each socket
let socket_tasks = sockets.into_iter().map(|socket| {
    let socket_addr = socket.peer_addr().unwrap();
    let buf = buffers.get_mut(&socket_addr).unwrap();
    socket
        .recv_from(buf)
        .and_then(|_| async move { Ok(socket_addr) })
});

// wait for the first socket to return a value (DOESN'T WORK)
let buffer = try_join_all(socket_tasks)
    .and_then(|socket_addr| async { Ok(buffers.get(&socket_addr)) })
    .await

However this does not work because futures::future::try_join_all drives all futures to completion and returns a Vec<(SocketAddr)>. I want to get the result when a single future completes and get just a SocketAddr--something akin to select! but over a collection.

How can this be done?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

清风无影 2025-02-18 19:48:02

如果您只需要第一个未来,也可以使用 :未来:: select_all() 。如果有很多期货FuturesUnordered可能会更具性能减少工作。

If you only need the first future you can also use futures::future::select_all(). If there are many futures FuturesUnordered may be more performant because it only polls future when they awake, but if there are few select_all() is likely to be more performant as it is doing less work.

遇到 2025-02-18 19:48:02

futuresunordered是一个将以他们完成的顺序产生期货结果。您可以socket_tasks.collect()进入此类型,然后使用 next() streamext 的方法,创建一个未来,该未来将在整个未来的第一个未来时完成收集完成。

FuturesUnordered is a Stream that will produce the results of futures in the order they complete. You can socket_tasks.collect() into this type, and then use the next() method of StreamExt to create a future that will complete when the first future in the whole collection completes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文