更新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