使用jQuery承诺模拟同步调用

时间:2014-03-31 16:16:12

标签: javascript jquery promise

我一直在使用bootbox.js库,它以异步方式运行,但我需要以同步方式使用它(例如,在提交表单之前设置“确认”窗口)。

我不想使用e.preventDefault()取消活动,我想推迟操作,直到用户响应模式。目前该库不支持它,但我很好奇是否可以使用promises模拟同步行为?

这是一个非常基本的例子,使用链接(而不是表单提交按钮,这是我的最终目标): http://plnkr.co/edit/5NovsuKTeQ7y6SKNTwWp?p=preview

3 个答案:

答案 0 :(得分:1)

不,这不是承诺所做的。承诺在这里无法帮助你。

链接的默认操作是导航到另一个页面(或转到此页面中的某个部分)。如果你想阻止一个链接做它的事情 - 你使用e.preventDefault()或从onclick处理程序(最好是前者)返回false。

preventDefault 完全你需要的东西,听起来就像你的目标。

confirm有效吗?!

是的,确实如此,没有人真正知道原因 - 阻止是confirm promptalert的原始行为,并且从未因为向后兼容性而改变。它完全阻塞,没有任何事情发生 - 这与语言和其他API不同,并且非常不典型。 - 例如:

setTimeout(function(){ 
    alert("World");
},100);
alert("Hello");

这里,"World"在关闭“Hello”框之前不会出现问题,即使它只有100毫秒超时。 alertprompt只是“冻结”JavaScript执行。它们被认为是糟糕的用户体验,除了非常具体的问题外,通常是一个糟糕的选择。

那么承诺是什么?

Promises是延迟计算的抽象,它们允许你创建看起来像是同步的非常好的异步代码,但它们并不神奇,并且它们不会将代码变为实际上同步。所有的承诺都是使编码异步代码几乎与编写同步代码一样简单

答案 1 :(得分:0)

我遇到了同样的问题,我发现一个解决方案是使用隐藏按钮:

<button id="submit" type="submit" style="display:none;">x</button>
<button id="send_submit" type="button">y</button>

然后在js代码中,

$("#send_submit").click(function(e){
    bootbox.confirm("Really want to do this ?", function(result){
        if(result)
            $("#submit").click();
    })
})

这不是一个漂亮的方法,但它的工作方式与你想要的一样,其他方式就像你说的那样,对事件使用prevenDefault,并逐个捕获所有传入的数据,然后用.post发送;

答案 2 :(得分:0)

我也使用Bootbox遇到了这个问题。这就是我解决的方法。

看看这个“删除”表单:

<form action="route/to/action" method="POST">
  <!-- these two instructions depend on your framework -->
  @method('DELETE')
  @csrf

  <!-- The submit button in the form, change it to type="button". -->
  <!-- This prevent the form submission without the user's confirmation. -->
  <button type="button" id="delete" title="Delete element">
    Delete
  </button>
</form>

然后,添加点击事件监听器,以编程方式调用submit()事件。

  let deleteButton = document.getElementById('delete');

  deleteButton.addEventListener('click', (ev) => {
    bootbox.confirm('Delete this element?', (confirma) => {
      if (confirma) {
        return $(ev.target)[0].form.submit(); 
      }
    })
  });