首页 > 解决方案 > 如何在 ASP.NET Core API 中等待异步执行?

问题描述

我正在使用 ASP.NET Core API 创建一个 API,我使用依赖于 Redux 和 Sagas 的 React 应用程序在客户端使用该 API。关键是,在我的客户端应用程序中,我一个接一个地执行两个 API 调用。一是注册新用户,二是注册用户在表单中指定的新公司,并将新注册的用户添加到该组织。所以它基本上在我的后端调用了两个方法。

我首先调用的注册函数如下所示:

[AllowAnonymous]
[HttpPost("~/api/account/register")]
public async Task<IActionResult> Register([FromBody]RegisterViewModel model)
{
    var user = new MyUser
    {
        UserName = model.Email,
        Email = model.Email,
    };

    var result = Task.Run(async () => { return await _userManager.CreateAsync(user, model.Password); }).Result;
    if (result.Succeeded)
    {
           // Partially removed for brevity.
    }
}

作为第二个 API 调用的一部分调用的我的另一个方法如下所示:

[HttpPost]
public async Task<IActionResult> Post([FromBody]OrganizationModel model)
{
    // Partially removed for brevity.
    try
    {
        var org = _mapper.Map<OrganizationModel, Organization>(model);

        var user = await _userManager.GetUserAsync(HttpContext.User);
        if (user == null) return BadRequest(ErrorMapper.MapError("post_failed"));

        org.Admins.Add(user);

        _repository.Add(org);
        var result = await _repository.SaveAllAsync();
        if (result) return Created($"/api/organizations/{org.Id}", _mapper.Map<Organization, OrganizationModel>(org));
        else return BadRequest(ErrorMapper.MapError("post_failed"));
    }
    catch (Exception ex)
    {
        _logger.LogError($"Failed to add a new organization: {ex}");
    }
}

所以,基本上就像你在第二种方法中看到的那样,我想获取当前用户(请注意,注册用户后我会自动登录用户),并将当前用户添加到组织的管理员列表中。

经过一些调试后,我注意到Register调用了方法,并且调用了以开头的类似方法var result = ...,但是没有调用下一行if (result.Succeeded),而是立即跳转到显示的第二个方法并继续执行它,直到var user = ...到达点没有用户将登录并且user将为空,因此它将退出此方法并移回该Register方法并继续该行if (result.Succeeded)。我希望整个Register方法在执行第二种方法之前执行。Register在转移到另一个方法之前,我如何才能等待该方法完全执行?

编辑:

客户端代码如下所示:

if (!error) {
    // Partially removed for brevity.
    const user = {
        email: emailInput,
        password: passwordInput,
        confirm_password: confirmInput,
    };
    signup(user);

    const org = {
        name: newOrganizationInput,
    };
    addOrganization(org);

    this.resetState();
}

标签: c#asp.net-core

解决方案


await您使用关键字等待异步方法的执行。但是,您的问题不在于后端,而在于客户端。

fetch/ JavaScript 中的 AJAX 调用是异步的。所以后端是否等待并不重要,客户端仍然会在不等待的情况下访问两个端点。

你可能正在做类似的事情:

fetch('/api/account/register', { ... });
fetch('/api/organizations', { ... });

fetch 方法异步执行并返回一个promise。你需要做的是:

await fetch('/api/account/register', { ... });
await fetch('/api/organizations', { ... });

或者

fetch('/api/account/register', { ... }).then(x =>
  fetch('/api/organizations', { ... });
);

推荐阅读