类型不匹配解决 <impl std::future::Future as std::future::Future>::Output == std::result::Result<wasm_bindgen::JsValue, wasm_bindgen::JsValue>

type mismatch resolving <impl std::future::Future as std::future::Future>::Output == std::result::Result<wasm_bindgen::JsValue, wasm_bindgen::JsValue>

我正在尝试使用 wasm_bindgen 和异步调用来实现 API class。

#![allow(non_snake_case)]

use std::future::Future;

use serde::{Deserialize, Serialize};
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use wasm_bindgen_futures::JsFuture;
use js_sys::Promise;
use web_sys::{Request, RequestInit, RequestMode, Response};
use wasm_bindgen_futures::future_to_promise;

use crate::fetch_example::*;


#[wasm_bindgen]
#[derive(Debug, Serialize, Deserialize)]
pub struct API {
    root: String,
}


#[wasm_bindgen]
impl API {
    pub fn new(root: &str) -> Self {
        Self {
            root: root.to_string(),
        }
    }

    pub fn getVersion(&self) -> Promise {
        let url = format!("{}/version", self.root);

        future_to_promise(async move {
            _request_json(&url, "GET")
        })
    }

    // other methods ...
}


// What is the correct returned type instead of Result<JsValue, JsValue> ???
async fn _request_json(url: &str, method: &str) -> Result<JsValue, JsValue> {
    let mut opts = RequestInit::new();
    opts.method(method);
    opts.mode(RequestMode::Cors);

    let request = Request::new_with_str_and_init(&url, &opts)?;

    request.headers().set("Accept", "application/json")?;

    let window = web_sys::window().unwrap();
    let resp_value = JsFuture::from(window.fetch_with_request(&request)).await?;

    let resp: Response = resp_value.dyn_into().unwrap();

    let json = JsFuture::from(resp.json()?).await?;

    Ok(json)
}

正如所见,我将 HTTP 调用取出到一个单独的私有函数中 _request_json 以避免不同 API 方法中的代码重复(它们应该是多个,而不是 getVersion 仅)。

我从这里获取了 HTTP 调用的基本示例:https://rustwasm.github.io/wasm-bindgen/examples/fetch.html

另外我发现struct方法的异步调用应该借助future_to_promise来实现:https://github.com/rustwasm/wasm-bindgen/issues/1858

所以问题出在 _request_json 的返回类型上。猜不对

当我编译项目时出现错误:

type mismatch resolving `<impl std::future::Future as std::future::Future>::Output == std::result::Result<wasm_bindgen::JsValue, wasm_bindgen::JsValue>`

如果我在 future_to_promise 中复制 _request_json 的正文,一切正常。

_request_json 使代码有效的正确返回表达式是什么?

这个结构:

async move {
    _request_json(&url, "GET")
}

具有类型 impl Future<Output = impl Future<Output = Result<JsValue, JsValue>>>

你可以这样修复:

future_to_promise(async move {
    _request_json(&url, "GET").await
})

可能也喜欢这样:

future_to_promise(_request_json(&url, "GET"))