jQuery validation
套件支援一個選項參數
submitHandler
可以替換掉原生的
submit()
方法,讓我們自己決定之後要怎麼處理送出的行為(例如可以改成使用 AJAX 來送出資料)。
在我的一個使用案例中,我會去判斷當前的環境,然後根據結果來決定我要用 AJAX 送出資料還是用原生的
submit()
送出。今天因為一些底層架構的修改,使得我判斷當前環境的動作變成是非同步的判斷,因此我就直覺地把我的 handler 改成了
async
函數並且在裡面
await
我的判斷結果,然後再看看怎麼處理。
可是結果程式就爆炸了,不管怎樣表單就是會變成以原生形式送出,根本沒有等到我的
await
執行完,而且我下了中斷點也根本跑不到我
await
之後的下一行。研究了老半天,我才得到一個結論:不可以直接把一個
async
函數傳過去當作
submitHandler
,否則就是會這樣。取而代之地,應該先傳入一個同步函數(lambda 函數也可以),然後才是在那個函數裡面呼叫我的
async
函數(且不要傳回),類似下面這樣:
async function handler(form) {
// 一些非同步的處理
$('#form').validate({
submitHandler: form => { handler(form); }
至於為什麼會這樣,我在官方的文件裡面翻來翻去就是沒看到答案,但是我跑去爬了一下 jQuery validation 的原始碼大概就知道是怎麼回事了:原來這個 submitHandler
如果有傳回值的話,是會根據這個傳回值(隱晦轉成 bool)來決定要不要以原生形式送出表單的。而 async
函數會傳回一個 Promise
物件,隱晦轉換就是 true
,所以一旦裡面跑到了非同步需要等候的地方,表單馬上就以原生形式送出了,所以我下一行的中斷點自然永遠到不了。取而地之地,只要 submitHandler
沒有傳回值,jQuery validation 就會完全交給我們的 handler 去決定一切。
近期留言