更新WordPress的元數據時,這裏的情形:我建立一個WordPress的插件來管理一些調查研究,我是參與項目的管理是能夠上傳從WP管理界面csv文件。在客戶端,當文件被上傳它通過文件的每一行,提取有關用戶的必要的信息,然後做一個AJAX調用參與者添加到項目中。我決定來解析客戶端上的csv文件,並通過提交一個Ajax請求一個,這樣我可以更新進度條爲每個收益。 JavaScript的看起來是這樣的:併發問題通過AJAX
$('#csv_upload_button').click(function() {
// declare the necessary variables
var f = $('#csv_file_input')[0].files[0],
fr = new FileReader,
rows, headers, dialog, count, remaining;
// when the file loads
fr.onload = function() {
// get the rows, the count, number remaining to process, and headers
rows = fr.result.split("\n");
remaining = count = rows.length - 1; // -1 to account for header row
headers = $.trim(rows[0]).split(',');
// create the dialog box to show the progress bar
dialog = $('<div></div>')
.html(
'<p>Loading...</p>' +
'<p><progress id="csv_upload_progress" max="' + count +
'" min="0" value="0"></p>')
.dialog({ modal: true; });
// then for each row in the file
$(rows).each(function(i, r) {
// create an object to hold the data
var data = {}, row = $.trim(r).split(','), j;
if (i > 0) { // data starts on the second row
// map the data into our object
for (j = 0; j < headers.length; j++) {
data[ headers[ j ] ] = row[ j ];
}
// send it to the server
$.post(
ajaxurl,
{
action: 'import_panel_member',
data: data,
postid: $('#post_ID').val()
},
function(result) {
var prog = $('#csv_upload_progress');
prog.attr('value', prog.attr('value') + 1);
if (0 == --remaining) {
// stuff to do when everything has been loaded
}
}
);
}
});
};
// read the csv file
fr.readAsText(f);
});
的PHP看起來是這樣的:
function import_panel_member() {
header('content-type: application/json');
// get the variables sent from the client
$postid = $_POST[ 'postid' ];
$data = $_POST[ 'data' ];
/*
* ...do other things involving talking to a 3rd party server...
*/
// get the WP meta data variable to be updated
$participants = get_post_meta($postid, '_project_participants', true);
// modify it
$participants[] = $data;
// update the database
update_post_meta($postid, '_project_participants', $participants);
// return a message to the client
echo json_encode((object) array('success' => 1, 'message' => 'added'));
exit;
}
的問題是,由於這些請求是異步的,看來該_project_participants
元數據字段只被更新最後一條記錄被處理。換句話說,只有列表中的最後一個人出現在參與者列表中。這裏有一些事情,我已經試過:
- 變化
$.post()
到$.ajax()
並設置async: false
這工作,但它是慢得多(由於同步調用),並由於某種原因,它可以防止我的對話框無法顯示直到所有的ajax調用完成。 - 將整個csv文件上傳到服務器並在那裏處理
而不是解析客戶端上的csv。這也適用,但我不認爲我可以從服務器獲得中間反饋,我可以使用它來更新進度欄。此請求可能需要很長時間,我不希望用戶在請求完成之前「放棄」請求。這樣做時,服務器有時不會響應ajax調用。
所以,也許我很貪心,只是想要我的蛋糕,也吃了它。我如何利用異步請求的速度,這使我有機會通過進度條爲用戶提供反饋,但不會因服務器上的併發問題而陷入困境?
您也可以上傳整個事情一次,並使用[瞬變API(http://codex.wordpress.org/Transients_API)跟蹤的過程。客戶端然後可以輪詢服務器並根據緩存中的值獲取處理狀態。 – doublesharp
哦!不知何故,我錯過了那個API。我可能會在我的下一個重構中做一個... – morphatic