JavaScript回调-为什么不起作用?

时间:2019-03-16 22:59:35

标签: javascript mysql callback

我希望代码如何工作:

  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 个答案:

答案 0 :(得分:1)

我认为您需要通过设置send来回拨onreadystatechange通话。您要在发送HTTP请求之前 注册回调:

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

但是您可能会发现Fetch API比使用旧的XMLHttpRequest方法更容易使用。就像@Raymond的建议一样,它基于Promise。缺点是IE或Edge不能完全支持它。

如果需要更好的浏览器支持,请尝试axios,这是一个基于Promise的开源HTTP客户端库,具有很多社区支持。

答案 1 :(得分:0)

我曾经遇到过这个问题,最终我把Node.JS MySQL插入函数放在了一个诺言中。这样,我们知道它已经完成,然后再继续在后端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
});

答案 2 :(得分:0)

@benjarwar“通过设置onreadystatechange来撤消发送呼叫”解决了该问题!

感谢@benjarwar和@Raymond的帮助。我将阅读Promise,因为我在这个问题上花费了太多时间。