【问题标题】:Convert synchronous Ajax calls to asynchronous将同步 Ajax 调用转换为异步
【发布时间】:2018-01-12 03:43:47
【问题描述】:

我有数百个类似这样的主 JS 脚本,我可以修改:

> some code filling parameter1
var response1=callAjax(parameter1);
> some code using response1 and filling parameter2
var response2=callAjax(parameter2);
> etc ..

callAjax 函数可以更改或重写。它目前以同步模式调用 Ajax(已弃用),因此需要对其进行大修。在执行主文件期间阻止 UI 是一项要求(这些是银行和类似应用程序,因此最终用户不允许在此过程中编辑任何输入字段或单击任何按钮 - 可以显示屏幕面纱)。

如何修改 callAjax 函数以使用异步模式并保持主脚本(数百或数千个)保持不变?

我查看了使用 Promises 或 async/await,但不知道如何使用这些来将 ajax 响应返回到主脚本。与添加一些用作信号量的全局变量相同。同样,不允许将主脚本分解为每个调用的多个函数。这些是纯 Javascript,没有 jQuery。

【问题讨论】:

  • 显示您的 callAjax 函数,以便我们了解您提出请求的具体情况
  • 不,您必须编辑该代码以使其异步工作。但是,如果您无论如何都在寻找糟糕的用户体验,为什么不让它保持同步呢?

标签: javascript ajax asynchronous promise


【解决方案1】:

如何修改 callAjax 函数以使用异步模式并保持主脚本(数百或数千个)保持不变?

你不能。如果使用异步 ajax,则无法从函数返回值,因为函数将在值可用之前返回。您根本无法将异步操作转换为同步函数。有关从函数返回异步操作的更多详细信息,请参阅How do I return the response from an asynchronous call?。您将看到所有可用选项都涉及在异步值完成时调用回调或返回一个承诺,并在承诺上使用带有.then() 的回调来了解该值何时完成以及它是什么。

如果您的要求是阻止 UI 并且您不能更改调用代码,那么您必须坚持使用同步 Javascript。也没有异步操作。

否则,摆脱这些要求并编写适当的异步调用代码,并且不要以这种方式阻塞 UI(您可以在 ajax 操作期间使用不同的技术保护屏幕内容不被编辑或按钮按下)。


因此,我从您所描述的问题得出的结论是,您需要提升当前的一些要求,因为没有解决方案:

  1. 阻止用户界面
  2. 仅使用异步 Ajax
  3. 直接从callAjax()返回ajax获取的值
  4. 不改变调用callAjax()的调用代码

你不能一次完成所有这些。

向前推进的设计选择是从callAjax() 返回一个promise,并修复所有使用它的调用代码以使用该promise。为了阻止 UI,您必须使用某种 UI 保护(屏幕面纱,您称之为屏幕面纱,或类似的东西)。


如果您有大量代码使用这个旧的同步 ajax 函数,我的建议是创建一个具有不同名称的新 ajax 函数,该函数返回一个承诺,并且不赞成将旧的用于任何新代码(让所有新代码使用新的)。然后,根据需要和业务目标的指导,重写旧功能的使用,一次使用一个新功能。这至少会停止使用旧的同步 ajax 代码编写更多代码。而且,随着时间的推移,它会让您有机会根据需要将代码转换为新界面。


请注意,调用看起来与您所拥有的代码(但仍需要更改)最接近的方法是使用 async/await(在 ES7 规范或转译器中可用)。你会从callAjax() 返回一个promise,然后调用者可以await 得到结果:

// async function returns a promise
async function someFunction() {
    try {
        // some code filling parameter1
        var response1 = await callAjax2(parameter1);
        //  some code using response1 and filling parameter2
        var response2 = await callAjax2(parameter2);
        // etc...
    } catch(e) {
        // handle error here
    }
}

附:看起来您当前的代码没有很好的方式来传达 ajax 错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-02
    • 1970-01-01
    • 1970-01-01
    • 2015-06-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多