Обратный вызов Javascript - Почему это не работает? - PullRequest
0 голосов
/ 17 марта 2019

Как я хочу, чтобы мой код работал:

  1. Веб-сайт отправляет SQL-вставку в базу данных.(Я использую POST и Node.js)
  2. Веб-сайт ожидает rowID для записи базы данных, которая будет создана
  3. Node.js отправляет обратно только что вставленный rowID
  4. DOM обновлен

Как работает мой код:

  1. Веб-сайт отправляет SQL-вставку в базу данных.(Я использую POST и Node.js)
  2. Я написал функцию Sleep, потому что веб-сайт не ожидает rowID
  3. Node.js отправляет обратноrowID, который был только что вставлен
  4. DOM обновлен

Я думал, что правильно написал функцию обратного вызова, чтобы это работало.Тем не менее, DOM корректно обновляется только когда я создал функцию сна.Код, который я написал, чтобы заставить это работать, не является правильным способом реализовать это, и я хотел бы сделать это правильно.

//add a record to the table
function addRecord() {
	
	event.preventDefault();
	
	var newTech = document.getElementById("newTechnician");
	
	if(newTech.elements.firstnameInput.value.length === 0 || newTech.elements.lastnameInput.value.length === 0 )
	{
		console.log("User didn't enter any data");
	}
	else {
		  
		  //stackoverflow.com/questions/9713058/send-post-data-using-xmlhttprequest
		var http = new XMLHttpRequest(),
		method = 'POST',
		url = '/tech';
		
		//build the url
		var usersInput = "type=insert&First_Name="+newTech.elements.firstnameInput.value+    
							"&Last_Name="+newTech.elements.lastnameInput.value;
			
		http.open(method, url, true);
		
		//Send the proper header information along with the request
		http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
		
		function updateDatabase (callback) {
			
			http.send(usersInput);	
			http.onreadystatechange = () => callback();
		}
		
		function sleep(milliseconds) {
			  var start = new Date().getTime();
			  for (var i = 0; i < 1e7; i++) {
				if ((new Date().getTime() - start) > milliseconds){
				  break;
				}
			  }
		}
		
		function callbackFunction () {	
			//developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/readyState
			if(http.readyState == 4 && http.status == 200) {
				if(http.status >= 200 && http.status < 400){
		
					//added because callback isn't working correctly and isn't waiting until 
					//it receives a response with the rowID from Node.js/mySQL database
					sleep(500);
					
					//add the new row to the table
					var response = JSON.parse(http.responseText);            
			
					//without the sleep function, id is undefined
					var id = response.rowID;

					var table = document.getElementById("technicianTable"); 

					//-1 add record at the end of the table
					var row = table.insertRow(-1);                         

					var newTechID = document.createElement('td');                
					newTechID.textContent = id;
					row.appendChild(newTechID);

					var newFirstName = document.createElement('td');                
					newFirstName.textContent = newTechnician.elements.firstnameInput.value;
					row.appendChild(newFirstName);
					newTechnician.elements.firstnameInput.value = "";

					var newLastName = document.createElement('td');                
					newLastName.textContent = newTechnician.elements.lastnameInput.value;
					row.appendChild(newLastName);
					newTechnician.elements.lastnameInput.value = "";
					 
					var newWorkoutDeleteCell = document.createElement('td');             
					var newWorkoutDeleteBtn = document.createElement('input');            
					newWorkoutDeleteBtn.setAttribute('type','button');
					newWorkoutDeleteBtn.setAttribute('name','deleteButtonValue');         
					newWorkoutDeleteBtn.setAttribute('value','Delete');
					newWorkoutDeleteBtn.setAttribute('onClick', 'deleteRecord(' + id + ')');
					var deleteRowID = document.createElement('input');             
					deleteRowID.setAttribute('type','hidden');
					deleteRowID.setAttribute('id', 'identifer' + id);
					newWorkoutDeleteCell.appendChild(deleteRowID);
					newWorkoutDeleteCell.appendChild(newWorkoutDeleteBtn);         
					row.appendChild(newWorkoutDeleteCell);                         
				}
		
			}
		};
		
		updateDatabase(callbackFunction);
	}
}

Ответы [ 3 ]

1 голос
/ 17 марта 2019

Я думаю, вам нужно отменить ваш send вызов с настройкой onreadystatechange.Вы хотите зарегистрировать свой обратный вызов до отправки HTTP-запроса:

        function updateDatabase (callback) {
            http.onreadystatechange = () => callback();
            http.send(usersInput);  
        }

Но вам может показаться, что с Fetch API легче работать, чем с более старым XMLHttpRequest методы.Как и предложение @ Raymond, оно основано на Promise.Недостатком является то, что он не полностью поддерживается в IE или Edge.

Если требуется лучшая поддержка браузера, попробуйте axios , клиентскую библиотеку HTTP с открытым исходным кодом, основанную на Promise, с большой поддержкой сообщества..

0 голосов
/ 17 марта 2019

@ benjarwar «Отмена отправки вызова с настройкой onreadystatechange» исправила проблему!

Спасибо @benjarwar и @Raymond за вашу помощь. Я прочитаю Обещание, потому что я потратил слишком много времени на эту проблему.

0 голосов
/ 17 марта 2019

Раньше у меня была эта проблема, я закончил тем, что вставил свою функцию вставки MySQL Node.JS в обещание.Таким образом, мы знаем, что он заканчивается до того, как мы продолжим работу на внутреннем сервере Node.JS.Мне было трудно с этой точной вещью, пока я не переключился на обещание.Мои функции MySQL будут завершены, но в ответе не будет данных.

function insert() {
    return new Promise((reoslve, reject) => {
        let results = []; // Store results
        con.connect(function(err) {
            if (err) throw reject(err); // Reject errors
            console.log("Connected!");
            con.query(sql, function (err, result) {
                if (err) throw err;
                console.log("Result: " + result);
                results.push(result); // Push result to results array
            });
            resolve(results); // We made sure we waited
        });
    })
}

insert().then((response) => {
    // Success, made sure it finishes
    // console.log(response);
}).catch((error) => {
    // Error's
});

Пример базового обещания

function insert() {
  return new Promise((resolve, reject) => {
      setTimeout(function() {
        resolve('Response')
      }, 500);
      // reject() for errors
  });
}

console.log('This runs first');
// This runs, and wait's for respoinse
insert().then((response) => {
  // We waited for response first
  console.log('Our new promise callback', response);
}).catch((error) => {
   // Error
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...