나는 내가 작성한 페이스 북 게임을위한 새로운 기능을 연구하고 있습니다. 게임을 통해 플레이어는 유럽의 도시를 여행하고 수익을 위해 물품을 배달 할 수 있습니다. 내가 추가하고있는이 기능은 길 찾기 AI를 게임에 추가합니다. 플레이어가 이동할 도시를 선택할 수있게되면 게임은 시작 도시에서 목적지 도시까지 플레이어의 기차를 자동으로 이동시킵니다. 나는 AJAX와 setTimeout()을 사용하여 백엔드에서 데이터를 가져와 도시를 연결하는 트랙을 따라 열차의 움직임을 가능하게하고있다. (의도적으로) 내가하려고하는 것을 더 잘 이해할 수있는 코드를 참조하십시오.AJAX 요청을 동기화하려고 시도했습니다.
문제는 setTimeout()이 너무 자주 호출되는 것입니다. 나는 statusFinalDest라는 전역 변수를 두 었는데, ENROUTE와 ARRIVED 두 값을 가질 수 있습니다. 열차가 ENROUTE 인 동안 JS 열차 이동 함수는 백엔드가 ARRIVED의 statusFinalDest를 반환 할 때까지 setTimeout을 사용하여 자체 호출합니다.이 시간이 지나면 기차 이동 시간 초과 루프가 (아마도) 종료됩니다. 그러나 myEventMoveTrainManual()을 백엔드 프로세스마다 한 번씩 호출하는 대신 statusFinalDest의 변경된 상태를 인식하지 않는 것처럼 매우 자주 호출됩니다. 이 과도한 행동을 끝내기 위해 코드에 제한 구조를 추가하려고 시도했지만 작동하지 않는 것으로 보입니다.
가 여기에 해당 FBJS의 (페이스 북 JS) 코드 : 여기
function myEventMoveTrainManual(evt) {
if(mutexMoveTrainManual == 'CONTINUE') {
//mutexMoveTrainManual = 'LOCKED';
var ajax = new Ajax();
var param = {};
if(evt) {
var cityId = evt.target.getParentNode().getId();
var param = { "city_id": cityId };
}
ajax.responseType = Ajax.JSON;
ajax.ondone = function(data) {
statusFinalDest = data.status_final_dest;
if(data.code != 'ERROR_FINAL_DEST') {
// Draw train at new location
trackAjax = new Ajax();
trackAjax.responseType = Ajax.JSON;
trackAjax.ondone = function(trackData) {
var trains = [];
trains[0] = trackData.train;
removeTrain(trains);
drawTrack(trackData.y1, trackData.x1, trackData.y2, trackData.x2, '#FF0', trains);
if(data.code == 'UNLOAD_CARGO') {
unloadCargo();
} else if (data.code == 'MOVE_TRAIN_AUTO' || data.code == 'TURN_END') {
moveTrainAuto();
} else {
/* handle error */
}
mutexMoveTrainManual = 'CONTINUE';
}
trackAjax.post(baseURL + '/turn/get-track-data');
}
}
ajax.post(baseURL + '/turn/move-train-set-destination', param);
}
// If we still haven't ARRIVED at our final destination, we are ENROUTE so continue
// moving the train until final destination is reached
// statusFinalDest is a global var
if(statusFinalDest == 'ENROUTE') {
setTimeout(myEventMoveTrainManual, 1000);
}
}
그리고 백엔드 PHP 코드 : 함수 myEventMoveTrainManual이 이벤트 핸들러에서 호출되는 경우
public function moveTrainSetDestinationAction() {
require_once 'Train.php';
$trainModel = new Train();
$userNamespace = new Zend_Session_Namespace('User');
$gameNamespace = new Zend_Session_Namespace('Game');
$this->_helper->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender();
$trainRow = $trainModel->getTrain($userNamespace->gamePlayerId);
$statusFinalDest = $trainRow['status_final_dest'];
if($statusFinalDest == 'ARRIVED') {
$originCityId = $trainRow['dest_city_id'];
$destCityId = $this->getRequest()->getPost('city_id');
if(empty($destCityId)) {
// If we arrived at final dest but user supplied no city then this method got called
// incorrectly so return an error
echo Zend_Json::encode(array('code' => 'ERROR_FINAL_DEST', 'status_final_dest' => $statusFinalDest));
exit;
}
$gameNamespace->itinerary = $this->_helper->getTrainItinerary($originCityId, $destCityId);
array_shift($gameNamespace->itinerary); //shift-off the current train city location
$trainModel->setStatusFinalDest('ENROUTE', $userNamespace->gamePlayerId);
$statusFinalDest = 'ENROUTE';
}
$cityId = $trainRow['dest_city_id'];
if($trainRow['status'] == 'ARRIVED') {
if(count($gameNamespace->itinerary) > 0) {
$cityId = array_shift($gameNamespace->itinerary);
}
}
$trainRow = $this->_helper->moveTrain($cityId);
if(count($trainRow) > 0) {
if($trainRow['status'] == 'ARRIVED') {
// If there are no further cities on the itinerary, we have arrived at our final destination
if(count($gameNamespace->itinerary) == 0) {
$trainModel->setStatusFinalDest('ARRIVED', $userNamespace->gamePlayerId);
$statusFinalDest = 'ARRIVED';
}
echo Zend_Json::encode(array('code' => 'UNLOAD_CARGO', 'status_final_dest' => $statusFinalDest));
exit;
// Pass id for last city user selected so we can return user to previous map scroll postion
} else if($trainRow['track_units_remaining'] > 0) {
echo Zend_Json::encode(array('code' => 'MOVE_TRAIN_AUTO', 'status_final_dest' => $statusFinalDest));
exit;
} else { /* Turn has ended */
echo Zend_Json::encode(array('code' => 'TURN_END', 'status_final_dest' => $statusFinalDest));
exit;
}
}
echo Zend_Json::encode(array('code' => 'MOVE_TRAIN_AUTO_ERROR'));
}
혼란스러운 점을 명확히하기 위해 myEventMoveTrainManual()은 이벤트 핸들러가 아니지만 이벤트 핸들러에서 호출됩니다. –