2012-10-31 91 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