2015-07-01 103 views
4

滿足所有觸發器時執行回調的慣用方式是什麼?觸發JavaScript回調的幾個事件

特別是,在下面的例子中,當用戶按下#btn時,運行proceed函數的方式是什麼,但不會早於先前啓動的AJAX請求返回響應(或者,如果用戶也按下按鈕早期,等待AJAX​​響應來臨之前發射proceed)?

proceed = (ajaxData) -> ... 

# Launch an AJAX request and display a button: 
$("#btn").on 'click', -> ??? 

$.ajax 
    type: "POST" 
    url: ... 
    data: ... 
    success: (ajaxData) -> ??? 
+0

顯示完整的代碼 –

+0

[向下滾動一路( http://api.jquery.com/jquery.ajax/)也看看beforeSend – ODelibalta

回答

1

使用的承諾,它存在於ES6,jQuery和其他框架(角...)

使用Promise.all(...)在ES6

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

您必須將所有ajax調用封裝在承諾中,然後Promise.all允許在所有承諾解決時調用。

也等同於jQuery的,看到這裏的例子: How do you work with an array of jQuery Deferreds?

+0

謝謝,這很有趣,看起來使用.when()/ .then()和JQuery延遲是一種方式解決方案,但正如我從文檔中所理解的那樣,在延遲中包裝按鈕單擊事件需要太多的代碼來處理一次性案例。 –

1

一個簡單的方法來實現這一點,只需使用一個布爾變量作爲標誌,並將其設置爲true,當AJAX請求成功:

proceed = function() {...}; 

ajax_completed = false; 

$.ajax(..., 
    success: function(data) { 
     ajax_completed = true; 
     ... 
    } 
); 

$("#btn").on('click', function(ev){ if(ajax_completed) {...} }); 
+0

對我來說不太合適 - 如果在接收數據之前單擊按鈕,點擊將被忽略... –

+1

@AlephAleph這似乎是習慣用法(*可能需要稍微修改/必要時修復*)。如果這不能回答這個問題,那麼你錯過了要清楚的問題。 –

0

每$ .ajax調用返回一個承諾

考慮一下:

var promise = $.ajax('...',{ 
    type: "POST" 
    url: ... 
    data: ... 
    success: callFunction() 
}); 

promise.done(function(result){ 
    //use result on your function 
}); 

無論如何,我不認爲禁用按鈕是最好的選擇UX這裏。考慮隱藏它或顯示一些消息。

+0

可能我沒有說清楚 - 該按鈕一定不能被禁用!在用戶提前按下按鈕的情況下,該操作被延遲直到收到內容 –

0

看起來,承諾/延期包裝是一種正確的做法,但似乎包裝按鈕點擊JQuery延期需要a lot of code一個看似簡單的事情。

供參考,這是我想出了這個特殊的情況下,什麼似乎一個一次性的解決方案的工作:

proceed = (ajaxData) -> ... 

proceedLock = {buttonClicked: false, data: null} 
tryProceed = -> 
    if proceedLock.buttonClicked and proceedLock.data? 
    proceed proceedLock.data 

# Launch an AJAX request and display a button: 
$("#btn").on 'click', -> 
    proceedLock.buttonClicked = true 
    tryProceed() 

$.ajax 
    type: "POST" 
    url: ... 
    data: ... 
    success: (ajaxData) -> 
    proceedLock.data = ajaxData 
    tryProceed()