如何使表单提交同步?

8
作为JavaScript的一种(包括表单提交),除了ajax调用之外,它是同步和单线程模型。这是正确的吗?但我遇到了一个与此有关的问题。
我在第1行提交表单,然后关闭弹出窗口。结果是self.close在表单提交之前被调用。所以它在异步模式下运行。表单提交是异步过程吗?如果是,如何使表单提交后的代码同步?(我不想使用setTimeOut和ajax)
以下是我的相关jsp代码
function clickSave()
 {

    document.form.action="customerAction.do";
    document.form.submit();// line 1
    self.close();// line 2

 }

更新:看起来我需要更正自己的说法,表单提交是异步过程,根据Is form submit synchronous or async?。那么问题来了,我该如何使self.close与表单提交同步呢?

1个回答

5
JavaScript(包括表单提交)是同步和单线程模型,除了Ajax调用。这是正确的吗?但我遇到了一个关于此的问题。
嗯,JS对于每个事件监听器都是异步的。Ajax允许异步模式,将结果作为事件返回。
JS大多数情况下不是并发的:一次只执行一个函数。然而,在最新版本中,有一些方法可以在JS中创建后台“并发”线程。
JS在单个线程上运行。(除了后台线程)
我在第1行提交表单,然后关闭弹出窗口。会发生的是self.close在表单提交之前被调用。这是不可能的。
表单提交是异步的,也就是说,JS将继续运行并结束。
你可以通过这个例子进行测试。
如果是,如何使表单提交后的代码同步?(我不想使用setTimeOut和ajax)
提交将重新加载整个页面,因此您的JS将结束,然后窗口将从服务器加载带有表单结果的新页面。您可以在这个新页面中包含一个新的JS来“继续”。
如果您不想重新加载整个页面,则必须使用AJAX,在这种情况下,您有两个选项:
异步:您可以设置事件监听器来接收和使用结果。
同步:您的页面将阻塞,直到结果准备好。
注意: (1):https://developer.mozilla.org/en-US/docs/Web/Guide/Performance/Using_web_workers?redirectlocale=en-US&redirectslug=DOM%2FUsing_web_workers (2):
<html>
    <body>
        <script type="text/javascript">
        function click2()
        {
            document.getElementById('form1').submit();
            for(var i=0; i < 1000000000; i++);
            window.open('http://www.stackoverflow.com');
        }
        </script>

        <button onclick="click2();"> click </button>
        <br/><br/>
        <form id="form1" action="http://www.duckduckgo.com" method="get">
            <input type="text" value="hello"/>
        </form>
    </body>
</html>

我认为我还可以做一件事情,就是创建带有self.close的script标签并返回到同一页。这将关闭窗口,那就是我想的。 - emilly
我正在第一行提交表单,然后关闭弹出窗口。问题在于,在表单提交之前就调用了self.close。我的意思是,由于表单提交是异步的,所以调用并没有到达服务器,而是在self.close执行之前就结束了。所以这是可能的 :) - emilly
1
不是调用,而是响应是异步的,调用始终是同步的,并且将始终发送到服务器。当然,如果服务器返回404或任何其他错误,您的JS将无法处理它。 - Adrian Maire
这并不是JavaScript或并发的正确定义。JavaScript已经同时运行了很长时间,否则,网页将是创建UI的可怕选项。并发意味着操作可以异步运行,因此它们不会阻止其他事情发生,但它们都在单个UI线程上运行。您所描述的是使用Web Workers的多线程,这对于AJAX调用或async/await操作并非必需。 - Mike Young
@MikeYoung:对我来说,异步并不意味着并发:你将事件推送到队列中,然后从事件循环中执行它们。没有两个事件或执行单元在并行或乱序运行(严格通过多个CPU核心/线程或通过操作系统调度)。如果没有工作线程,您永远不会面临内存/执行屏障(用于互斥、信号量、条件变量等)。 - Adrian Maire

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接