2012-10-31 68 views
0

更新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元数据字段只被更新最后一条记录被处理。换句话说,只有列表中的最后一个人出现在参与者列表中。这里有一些事情,我已经试过:

  1. 变化$.post()$.ajax()并设置async: false
    这工作,但它是慢得多(由于同步调用),并由于某种原因,它可以防止我的对话框无法显示直到所有的ajax调用完成。
  2. 将整个csv文件上传到服务器并在那里处理
    而不是解析客户端上的csv。这也适用,但我不认为我可以从服务器获得中间反馈,我可以使用它来更新进度栏。此请求可能需要很长时间,我不希望用户在请求完成之前“放弃”请求。这样做时,服务器有时不会响应ajax调用。

所以,也许我很贪心,只是想要我的蛋糕,也吃了它。我如何利用异步请求的速度,这使我有机会通过进度条为用户提供反馈,但不会因服务器上的并发问题而陷入困境?

回答

0

我想通了。答案是两种方法的混合。我可以使用一系列$.post()电话做,在异步模式下进行更好的东西,然后上传整个CSV做工作在同步模式更好的东西。如果不在SO中输入完整的解释,永远不会想到这一点!

+1

您也可以上传整个事情一次,并使用[瞬变API(http://codex.wordpress.org/Transients_API)跟踪的过程。客户端然后可以轮询服务器并根据缓存中的值获取处理状态。 – doublesharp

+0

哦!不知何故,我错过了那个API。我可能会在我的下一个重构中做一个... – morphatic