Asynchronous 在actix web中从多部分读取数据

Asynchronous 在actix web中从多部分读取数据,asynchronous,rust,actix-web,Asynchronous,Rust,Actix Web,我用actixwebv3.3.2和actixmultipartv0.3.0试过了 举个简单的例子 使用actix\u multipart::multipart; 使用actix_web:{post,web,App,HttpResponse,HttpServer}; 使用未来:{StreamExt,trysteamext}; #[职位(“/”) 异步fn保存_文件(mut有效负载:多部分)->HttpResponse{ 而让Ok(Some(mut field))=有效负载。请尝试下一步()。等待{

我用
actixwebv3.3.2
actixmultipartv0.3.0
试过了

举个简单的例子

使用actix\u multipart::multipart;
使用actix_web:{post,web,App,HttpResponse,HttpServer};
使用未来:{StreamExt,trysteamext};
#[职位(“/”)
异步fn保存_文件(mut有效负载:多部分)->HttpResponse{
而让Ok(Some(mut field))=有效负载。请尝试下一步()。等待{
让content_type=field.content_disposition().unwrap();
让filename=content\u type.get\u filename().unwrap();
println!(“文件名={}”,文件名);
而让一些(块)=field.next()等待{
让data=chunk.unwrap();
println!(“读块”);
}
println!(“完成”);
}
HttpResponse::Ok().finish()
}
#[actix_web::main]
异步fn main()->std::io::Result{
HttpServer::new(| | App::new().service(保存文件))
.bind(“0.0.0.0:8080”)?
.run()
.等待
}
这很好,但我想异步处理表单数据。所以我试着:

使用actix\u multipart::multipart;
使用actix_web:{post,web,App,HttpResponse,HttpServer};
使用未来:{StreamExt,trysteamext};
#[职位(“/”)
异步fn保存_文件(mut有效负载:多部分)->HttpResponse{
actix_web::rt::spawn(异步移动{
而让Ok(Some(mut field))=有效负载。请尝试下一步()。等待{
让content_type=field.content_disposition().unwrap();
让filename=content\u type.get\u filename().unwrap();
println!(“文件名={}”,文件名);
而让一些(块)=field.next()等待{
让data=chunk.unwrap();
println!(“读块”);
}
println!(“完成”);
}
});
HttpResponse::Ok().finish()
}
#[actix_web::main]
异步fn main()->std::io::Result{
HttpServer::new(| | App::new().service(保存文件))
.bind(“0.0.0.0:8080”)?
.run()
.等待
}
(将
actix\u web::rt::spawn
添加到
save\u文件

但这并没有起作用——消息
“Done”
从未打印出来。第二种情况下显示的
“读取数据块”
的数量少于第一种情况,因此我猜
字段.next().wait
在完成读取所有数据之前,由于某种原因无法终止

我不太了解异步编程,所以我不确定为什么
field.next()
actix\u web::rt::spawn中不起作用


我的问题是:为什么会这样?当你打这个电话时,我如何处理
actix\u web::rt::spawn

actix\u web::rt::spawn(异步移动{
//做事。。。
});
spawn
返回用于轮询任务的
JoinHandle
。当您删除该句柄(通过不将其绑定到任何对象)时,该任务将被“分离”,即在后台运行

actix
文档在这里没有特别的帮助,但是
actix
使用了
tokio
运行时。一个关键问题是,在东京
衍生任务不能保证完成。执行人需要知道,不知何故,它应该在未来执行工作。在第二个示例中,生成的任务从未
.await
ed,也没有通过通道与任何其他任务通信

最有可能的是,生成的任务从未被轮询,也没有取得任何进展。为了确保任务完成,您可以
.wait
调用
JoinHandle
(它将驱动任务完成)或
.wait
调用其他依赖于衍生任务中的工作(通常使用通道)的
未来的



至于您更一般的目标,工作已经异步执行了!最有可能的是,
actix
正大致执行您在第二个示例中尝试执行的操作:在收到请求时,它生成一个任务来处理该请求,并重复轮询该请求(以及其他活动请求),直到完成,然后发送响应。

进行此调用时:

actix\u web::rt::spawn(异步移动{
//做事。。。
});
spawn
返回用于轮询任务的
JoinHandle
。当您删除该句柄(通过不将其绑定到任何对象)时,该任务将被“分离”,即在后台运行

actix
文档在这里没有特别的帮助,但是
actix
使用了
tokio
运行时。一个关键问题是,在东京
衍生任务不能保证完成。执行人需要知道,不知何故,它应该在未来执行工作。在第二个示例中,生成的任务从未
.await
ed,也没有通过通道与任何其他任务通信

最有可能的是,生成的任务从未被轮询,也没有取得任何进展。为了确保任务完成,您可以
.wait
调用
JoinHandle
(它将驱动任务完成)或
.wait
调用其他依赖于衍生任务中的工作(通常使用通道)的
未来的



至于您更一般的目标,工作已经异步执行了!最有可能的是,
actix
正大致执行您在第二个示例中尝试执行的操作:在收到请求时,它生成一个任务来处理该请求,并重复轮询该请求(以及其他活动请求),直到完成,然后发送响应。

您的第一个代码已经是异步的。o您的第二个代码在完成读取传入数据之前发送
OK
响应,这可能会提示发件人停止发送,假设他们尚未完成。对不起,我的意思是“返回响应,然后处理表单数据”。啊,收到了。所以我应该首先获取数据,等待,然后返回respon