首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >异步/等待模式的问题--在C#和JavaScript中--如何返回同步值

异步/等待模式的问题--在C#和JavaScript中--如何返回同步值
EN

Software Engineering用户
提问于 2018-08-04 01:47:26
回答 4查看 1.4K关注 0票数 1

在旧风格的等待式无NodeJS中,当您调用一个具有异步方面的函数时,您将传入众所周知的回调,该回调在异步部分完成时被调用。这不会污染函数的返回值,而函数仍然可以同步地向调用方返回有意义的内容。

异步/等待模式现在的问题是,要使用它,必须决定函数是同步的还是异步的。这意味着,如果我有一个同步的现有函数,并且返回值将保持同步计算,并因此在函数返回时返回,我希望向其添加一个异步组件,之前我将添加一个回调,并更改调用方。但是现在我必须让返回值--异步值和原始返回值--找到另一种方法。那会是什么?

您会在C#中使用“out”参数吗?这不是最好的做法。您是否会传入一个对象,该对象的状态被修改以返回同步值?

当前的趋势是返回一个元组,并返回多个值的对象。但是,其中一个值可以通过同步而另一个值是异步的吗?

EN

回答 4

Software Engineering用户

发布于 2018-08-09 05:35:55

为什么你不能返回一个已经完成的任务?

C#:return Task.FromResult(...);

JavaScript:return Promise.resolve(...);

实际上,C#最近添加了ValueTask<T>,以避免为这个立即可用值的场景分配。

票数 3
EN

Software Engineering用户

发布于 2018-08-04 04:33:09

当前的趋势是返回一个元组,并返回多个值的对象。但是,其中一个值可以通过同步而另一个值是异步的吗?

你当然可以把它还回去。Tuple<Foo, Task<Bar>>。您可以这样创建它:

代码语言:javascript
运行
复制
// this is a function starting a task producing Bar
Task<Bar> GetBarAsync() {
    ...
}

...

Tuple<Foo, Task<Bar>> Baz()
{
    return Tuple.Create(
        new Foo(),
        GetBarAsync());
}

但是,由于这是SE,我想补充一点,我不清楚为什么您需要这样的功能。这显然把我的担忧混合在一起。异步函数并不意味着在调用时正在执行任何操作。事实上,它做了一些事情,但在一个典型的场景中它并不重要。

票数 0
EN

Software Engineering用户

发布于 2018-08-09 08:19:40

你为什么想要这个?继续使用BookFootnotes的例子,其中一个是同步的,另一个是异步的,它实际上应该是两个方法(或者至少两个方法调用),而不是一个,因为同步获取Book和使用脚注异步获取Book是两件稍微不同的事情。

从你的评论到另一个答案:

但是对于一个真正关心的客户来说,他想要等待任务的完成。如何将任务返回给来电者以及书。

您可以添加一个参数来指定要获取的内容。只有元数据(考虑到您的问题,我们假设元数据将快速返回)或扩展数据(不会很快返回)。

代码语言:javascript
运行
复制
public Book FetchBook(FetchBookOptions options);
public Task<Book> FetchBookAsync(FetchBookOptions options);

[Flags]
public enum FetchBookOptions
{
    None,
    Metadata = 1,
    Content = 2,
    Footnotes = 4,
    All = Metadata | Content | Footnotes
}

关心元数据、脚注和内容但需要保持响应性的客户端,可以调用。

代码语言:javascript
运行
复制
var book = await bookRepository.FetchBookAsync(FetchBookOptions.All);

不使用async/await但需要所有数据的客户端可以调用

代码语言:javascript
运行
复制
 var book = await bookRepository.FetchBookAsync(FetchBookOptions.All);

而只需要元数据的客户端(已知“立即”提供元数据)可以调用

代码语言:javascript
运行
复制
var book = await bookRepository.FetchBookAsync(FetchBookOptions.Metadata);

代码语言:javascript
运行
复制
var book = await bookRepository.FetchBookAsync(FetchBookOptions.Metadata);

最终你会做一些这样的事情

代码语言:javascript
运行
复制
private async void Button_OnClick()
{
    this.SetBooks(await bookRepository.FetchBookAsync(FetchBookOptions.Metadata));
    this.UpdateBooksFootnotes(await bookRepository.FetchBooksAsync(FetchBookOptions.All));
}

这完全实现了您想要的结果,立即设置原始书籍--考虑到FetchBookOptions.Metadata立即返回,或者至少很快返回--并且只要获取脚注,您就可以更新它们。

票数 0
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/376378

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档