2015-10-29 61 views
1

我有以下JavaScript模式。我試圖運行「getDataTwo」,只有在「getDataOne」完成後才能運行。這意味着XMLHttpRequest必須返回所有數據。我一直在四處尋找,我發現信息。回調和超時以及承諾。我不明白答案或解釋不符合我的特定代碼模式(我無法理解答案)。XMLHttpRequest:運行多個

當我這樣做: getDataOne(getDataTwo());

我得到了與上述不一致的結果,因爲XMLHttpRequest在下一個開始之前尚未啓動。所以每個人都試圖在對方的頂部工作 - 或多或少。

,當我嘗試這樣的事: this.getDataOne(函數(){ this.getDataTwo(); }); 這是一個微弱的回調嘗試(我認爲),只有一個函數往往會運行。

所以 - 我的問題 - 我怎樣才能可靠地讓'getDataTwo'只在整個'processRequest'從'getDataOne'調用完成時才運行?

請注意,我不想使用定時器功能(例如,只能在3秒後運行)。因爲,誰在說這段特定的字符串有多長。

下面的代碼模式:

this.getDataOne = function() { 
    myURL = this.returnURL(); 
    var xrRW = new XMLHttpRequest(); 
    this.processRequest(apiGSS, xrRW, myURL); 
} // end: getDataOne 

this.getDataTwo = function() { 
    myURL = this.returnURL(); 
    var xrRW = new XMLHttpRequest(); 
    this.processRequest(apiGSS, xrRW, myURL); 
} // end: getDataTwo() 

this.processRequest = function(iAPI, xReq, strCommand) { 

    xReq.onreadystatechange = function() { 
    if (xReq.readyState === 4) { 
     if (xReq.status === 200) { 

      // parse JSON data... 
      Do JSON work here 

      // write parsed data to screen... 
      // by calling a function and sending it the parsed JSON data 
      writeToScreen(arrayofJSONData()); 

      } // end: xReq.readyState === 200 
     } // end: xReq.readyState === 4 
    } // end: onreadystatechange 

    xReq.open("GET", strCommand, true); 
    xReq.send(null); 
} // end: processRequest 

回答

0

你八九不離十,你只需要實際傳遞和調用回調函數:

this.getDataOne = function() { 
    myURL = this.returnURL(); 
    var xrRW = new XMLHttpRequest(); 
    this.processRequest(apiGSS, xrRW, myURL, this.getDataTwo); 
} // end: getDataOne 

this.getDataTwo = function() { 
    myURL = this.returnURL(); 
    var xrRW = new XMLHttpRequest(); 
    this.processRequest(apiGSS, xrRW, myURL); 
} // end: getDataTwo() 

this.processRequest = function(iAPI, xReq, strCommand, onSuccess) { 

    xReq.onreadystatechange = function() { 
     if (xReq.readyState === 4) { 
     if (xReq.status === 200) { 
      if(onSuccess) { 
      onSuccess(); 
      } 
     } // end: xReq.readyState === 200 
     } // end: xReq.readyState === 4 
    } // end: onreadystatechange 

    xReq.open("GET", strCommand, true); 
    xReq.send(null); 
} // end: processRequest 

課程,進一步優化我會建議移動創造XHR對象也可以使用processRequest函數。

+0

我不知道是什麼與「if(onSuccess){onSuccess();}」。當我添加了所有建議的改變(除了我沒有推薦XHR對象 - 我會在稍後做...),只有getDataTwo運行... getDataOne不運行,即使這是所謂的主程序。 –

1

事實證明,我的代碼很笨拙。這是我的情況的解決方案(感謝回答的人,事實證明我沒有足夠的信息來幫助你理解我的全部情況)。

我現在正在成功地使用這個調用模式:「getDataOne(getDataTwo());」 (不含引號)。我在'getDataOne'和'getDataTwo'函數中做的不同之處在於,我沒有在單個數組中設置變量(未在我的原始代碼中顯示,對不起)。所以當getDataOne被調用時,它正在寫入getDataTwo依賴的同一個數組,並且進一步,returnURL和processRequest正在檢查相同的單個數組以獲取他們每個人必須做的事情。由於'最後一次更新數組',整體代碼將失敗。這裏是我的代碼現在正在做,而且做得很好,現在,它是不是想讀這是一個由相互競爭的功能(耶)有爭議的在單一陣列什麼是更好的共享:

getDataOne(getDataTwo()); 

this.getDataOne = function() { 
    myURL = this.returnURL("byOne type", "byOne query"); 
    this.processRequest(apiGSS, xrRW, myURL, "byOne Type"); 
} // end: getDataOne 

this.getDataTwo = function() { 
    myURL = this.returnURL("byTwo type", "byTwo query"); 
    this.processRequest(apiGSS, myURL "byTwo type"); 
} // end: getDataTwo() 

this.returnURL(byType, byQuery) { 
    // return a URL that matches the byType and byQuery requirements 
} 

this.processRequest = function(iAPI, strCommand, byType) { 

    var xReq = new XMLHttpRequest(); 

    xReq.onreadystatechange = function() { 
     if (xReq.readyState === 4) { 
     if (xReq.status === 200) { 

      if (byType === "byTwo type") { 
       // do this... 
      } else { 
       // do that... 
      } // end: (byType === "byTwo type") 

     } // end: xReq.readyState === 200 
     } // end: xReq.readyState === 4 
    } // end: onreadystatechange 

    xReq.open("GET", strCommand, true); 
    xReq.send(null); 
} // end: processRequest