如何强制事件回调等待异步调用解决?

时间:2020-07-29 15:12:04

标签: javascript asynchronous promise async-await dom-events

我有一个侦听名为onBeforeSubmit的事件的表单。我提交表单时会触发此事件,但是如果回调返回false,则会停止提交。

问题

我的回调涉及对API的异步调用。在决定是否返回false之前,我如何强制事件等待承诺解决?目前,它不等待fetch()解决-我已经尝试了async/await.then()这两种方法...

我尝试过的事情:

尝试1:

onBeforeSubmit: async (e) {
  const res = await fetch(url);
  // if res value fails some condition
  return false
}

尝试2:

onBeforeSubmit: (e) {
  fetch(url).then( res => {
  // if res value fails some condition
  return false
  })
}

await强制javascript是否要等到获取解析后才能继续下一行?

我还注意到,每当我输入async关键字时,它都会忽略return false语句并继续进行提交。是什么原因造成的?

编辑:这是第三方API,所以我无法控制onBeforeSubmit的行为:(

2 个答案:

答案 0 :(得分:3)

您有一个期望同步返回值的事件处理程序,但是您试图在该回调中运行异步操作。那只是在Javascript中不起作用。

运行异步函数时,您的回调函数将立即返回,异步函数将在其自己的回调中完成。如果将回调标记为async,则仅表示它立即返回一个Promise。由于onBeforeSubmit事件处理函数期望返回的是布尔值,而不是诺言,因此它无法正常工作。

Javascript中无法使此回调“等待”,因此它可以同步返回布尔值。

解决此问题的通常方法是始终返回false,因此不会自动提交表单。然后,运行您的异步操作,如果操作成功,那么您可以从该异步完成回调中手动提交表单(无需进一步验证)。

答案 1 :(得分:2)

我建议您使用event.preventDefault()阻止表单提交,然后提出您的fetch请求,如果响应值是false,则表单不是首先提交的,否则请删除表单的事件侦听器onsubmit,然后添加新的事件侦听器以提交表单

以下是您的代码外观的示例

var submitform=function sbmform(e){
  e.preventDefault()
  fetchvalue()
}
const form = document.getElementById('myform')
form.addEventListener('submit',submitform,false)

async function fetchvalue(){
  const res = await fetch(url);
 if (res=="to conditon"){  // set your condfiton
       return false
  }
 else{
  form.removeEventListener('submit', submitform, false);
  form.submit()
 }
}