1

我正在尝试向一个数据库处理程序发送一条消息,并根据结果向第二个处理程序发送一条消息,或者从第一个处理程序返回一个错误。

到目前为止,我想出的方法行不通;锈蚀 说match arms have incompatible types

expected struct 'futures::future::and_then::AndThen', found enum 'std::result::Result'

state
    .db
    .send(...)
    .from_err()
    .and_then(|res| match res {
        Ok(response) => {
        // Do some additional logic here
        state
        .db
        .send(...)
        .from_err()
        .and_then(|res| match res {
            Ok(response) => Ok(HttpResponse::Ok().json(response)),
            Err(err) => Ok(HttpResponse::InternalServerError().body(err.to_string()))
            }) 
        },
        Err(err) => Ok(HttpResponse::InternalServerError().body(err.to_string()))
    })
    .responder()

质疑如何在 actix-web 中完成此操作?

4

1 回答 1

2

你快到了。

使用 amatch时,所有臂必须产生相同的类型。在你的情况下,一个是未来结合and_then,在另一只手臂上,你有一个result.

此外,除非您的send()函数返回 type impl Future<Item = Result<R, E>, Error = E>,否则match完全是多余的。and_then作为参数Item,不是Result<Item, Error>

因此,整个事情可以简化为:

state
  .db
  .send(...)
  .from_err()
  .and_then(|res| state.db.send(...).from_err())
  .then(|res| match res {
     Ok(response) => Ok(HttpResponse::Ok().json(response)),
     Err(err) => Ok(HttpResponse::InternalServerError().body(err.to_string()))
   })
   .responder()

不过,让我们假设您的类型是正确的。您可以像这样轻松地将其转换Result为:futurefuture::result

state
    .db
    .send(...)
    .from_err()
    .and_then(|res| future::result(res).from_err())
    .and_then(|res| 
        // Do some additional logic here
          state
          .db
          .send(...)
          .from_err()
     )
     .and_then(|res| future::result(res).from_err())
     .then(|res| match res {
       Ok(response) => Ok(HttpResponse::Ok().json(response)),
       Err(err) => Ok(HttpResponse::InternalServerError().body(err.to_string()))
      })
     .responder()

沙箱上有一个例子:https ://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=6801886b02081160e268f395bcc1ad6c

于 2019-01-12T23:46:13.660 回答