被一个问题困惑了好久: 在一些业务场景下,一个远端数据可能会被多次使用,比如: get_res() 可以被多次调用,如果已经fetch 成功,就会立即返回,否则就会等待 fetch 结果。 这种写法可以避免回调函数。
const res = fetch("xxxxx");
// get_res 可以被多次调用。
async get_res() {
await res;
}
但是在rust中,future 文档里写到:一个 future 只能被 poll 一次。 否则有可能会有预期外的情况。 不知道在rust当中,有没有办法做到类似的效果
1
共 10 条评论, 1 页
评论区
写评论老哥, 你还是没理解啊, 先按你的javascript代码来说:
如果你想说的是情况二, 但你不能在rust里这么干, 因为rust有Ownership和Move Sematics:
另外你对rust Future实现和Poll机制不是很了解。
NotReady已经是过期很久的文档了,认准 docs.rs 商标。
而且我不知道你看的啥文档。
再仔细看看文档吧,不要囫囵吞枣。
--
👇
apawn: 文档中写到 fuse就是返回一个 NotReady,而不是立即返回数据 ?
👇
Mike Tang: Rust中早就为咱们考虑好了这种情况,.fuse() 一下就可以。
FusedFuture 查一下。其实就相当于包了一层,防止UB。
好的,谢谢回答 。 贴的代码是js 的, 在 js 里,get_res()返回了一个Promise,这个 Promise 已经被resolve 后,如果继续await,就会直接返回结果。
主要是为了解决一种业务场景,比如需要在passport获取当前用户,passport 提供一个异步函数 async getUser();
上层业务在调用的时候,直接await getUser() 结果即可,不需要判断是否已经ready了,如果没有ready,也不需要再二次请求,而是在第一次请求完成后一起resolve。如果没有ready,就直接返回结果。
这里 rust 的实现可能和js不太一样, 如果 await 一个 future,就相当于 poll 了一次,会额外再发出一次请求。 并且,如果对于已经ready的 future,无法 await 直接获取结果 。
--
👇
chansia: 有些不太明白你想问什么?你这里多次调用
get_res
没有任何问题,因为每次调用都会产生一个不同future,每一个future都会被Executor正确处理。如果每次请求结果都一样,而你又不想产生多次网络io,你可以把请求结果缓存起来,后续直接访问这个缓存,然后定时更新缓存。另外futures文档说的不是一个future只能poll一次,而是说底层实现Executor时,尽量避免多次低效poll future,而是等到future ready通知后,poll一次就好了有些不太明白你想问什么?你这里多次调用
get_res
没有任何问题,因为每次调用都会产生一个不同future,每一个future都会被Executor正确处理。如果每次请求结果都一样,而你又不想产生多次网络io,你可以把请求结果缓存起来,后续直接访问这个缓存,然后定时更新缓存。另外futures文档说的不是一个future只能poll一次,而是说底层实现Executor时,尽量避免多次低效poll future,而是等到future ready通知后,poll一次就好了文档中写到 fuse就是返回一个 NotReady,而不是立即返回数据 ?
👇
Mike Tang: Rust中早就为咱们考虑好了这种情况,.fuse() 一下就可以。
FusedFuture 查一下。其实就相当于包了一层,防止UB。
Rust中早就为咱们考虑好了这种情况,.fuse() 一下就可以。
FusedFuture 查一下。其实就相当于包了一层,防止UB。
对对对, 就是一个future 在ready 之后,还可以继续poll 多次吗 。简单来说,就是一个 future 被 await 多次
--
👇
Mike Tang: 一个Poll是被 Poll::Ready 一次,不是只能被 poll 一次。
一个Poll是被 Poll::Ready 一次,不是只能被 poll 一次。