如何实现异步电子邮件验证逻辑

本文关键字:电子邮件 验证 异步 何实现 实现 | 更新日期: 2023-09-27 17:52:43

我需要实现以下内容:我有一个用户输入电子邮件的页面。每次文本变化,我必须检查用户是否存在于数据库中,并根据该信息,我应该设置按钮的文本为"注册"或"登录"。问题是,这个DB请求可能需要几秒钟(原因无关紧要),并且API是异步的,因此事件处理程序将用async装饰,并且由于邮件条目可能更改多次,因此该处理程序将在任何一个结束之前被调用多次。我将有并发API请求然后可能并发尝试更改按钮文本这可能不会很好地结束。我想到了这样的东西:

private async void OnTextChanged(object sender, TextChangedEventArgs e)
{
    mailEntry.TextChanged -= OnTextChanged;
    ...
        submitButton.Text = (await api.AccountExistAsync(mailEntry.Text)).IsRegistered
                            ? "Sign in"
                            : "Sign up";
    ...
    mailEntry.TextChanged += OnTextChanged;
}

但是这个设计的一个问题是,比如说,在-= OnTextChanged+= OnTextChanged之间输入了一个有效的电子邮件,在这种情况下,它永远不会被检查。

我的问题是,实现我想要达到的目标的正确方法是什么?

如何实现异步电子邮件验证逻辑

这里有一个解决方案:

private long requestNumber;
private async void OnTextChanged(object sender, TextChangedEventArgs e)
{
    var text = mailEntry.Text;
    long myRequestNumber = ++requestNumber;
    await Task.Delay(200);
    if (requestNumber != myRequestNumber)
        return;
    var result = (await api.AccountExistAsync(text)).IsRegistered;
    if (requestNumber != myRequestNumber)
        return;
    submitButton.Text = result ? "Sign in" : "Sign up";
}

它维护一个requestNumber变量来保存最后的请求号,该请求号在每次更改文本时递增。

如果在AccountExistAsync操作完成后,代码发现变量被更改,它将得出已经发出新请求的结论,并且不会更新UI。

请注意,该解决方案在尝试发送验证请求之前也等待200毫秒。虽然这将延迟验证操作200毫秒,但它将防止发送太多请求,特别是当用户快速输入时。这当然是可选的。

编辑:

我在读取/更新requestNumber时删除了同步的使用,因为这样的代码只在UI线程中运行。