将同步Ajax调用转换为异步

时间:2018-01-12 03:43:47

标签: javascript ajax asynchronous promise

我有数百个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。

1 个答案:

答案 0 :(得分:2)

  

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

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

如果您要求阻止用户界面并且无法更改主叫代码,那么您必须坚持使用同步Javascript。没有异步操作也可以。

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

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

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

    你不能同时做所有这些。

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

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

    请注意,您可以使用async/await(在ES7规范或转换器中提供)来调用与您拥有的代码(但仍需要更改)相近的代码。您已从callAjax()返回承诺,然后调用者可以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
        }
    }
    

    P.S。看起来您当前的代码没有很好的方式来回复ajax错误。