0
votes

JavaScript Callback - Pourquoi ne travaille-t-il pas?

Comment je veux que mon code fonctionne:

  1. Site Web envoie un insert SQL à la base de données. (J'utilise un post et un nœud.js) li>
  2. Site Web attend le Rowid pour l'enregistrement de base de données qui sera créé LI>
  3. nœud.js envoie le railid qui a été inséré li>
  4. DOM est mis à jour li> ol>

    Comment mon code fonctionne: p>

    1. Site Web envoie un insert SQL à la base de données. (J'utilise un post et un nœud.js) li>
    2. J'ai écrit une fonction de sommeil car le site Web n'attend pas le Rowid STRUT> LI>
    3. nœud.js envoie le railid qui a été inséré li>
    4. DOM est mis à jour li> ol>

      Je pensais que j'ai écrit correctement une fonction de rappel afin que cela fonctionnerait. Cependant, le DOM n'est que correctement mis à jour lorsque j'ai créé une fonction de sommeil. Le code que j'ai écrit pour obtenir ce travail n'est pas la bonne façon de mettre en œuvre cela et je voudrais le faire correctement. P>

      p>

      //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);
      	}
      }


0 commentaires

3 Réponses :


0
votes

J'avais l'habitude d'avoir ce problème, j'ai fini par mettre mon nœud.js MySQL Insérer la fonction dans une promesse. De cette façon, nous savons qu'il se termine avant de continuer sur le serveur NODE.JS. J'ai eu du mal avec cette chose exacte, jusqu'à ce que je passe à la promesse. Mes fonctions MySQL complèteraient, mais les données ne seraient pas là dans la réponse. XXX PRE>

Exemple de la promesse de base p>

p>

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
});


0 commentaires

1
votes

Je pense que vous devez inverser votre appel appel avec paramètre onreadyStatechange . Vous souhaitez enregistrer votre rappel avant envoyer la requête HTTP: xxx

mais vous pouvez trouver le FETCH API plus facile à utiliser avec que l'utilisation de l'ancien XMLHTTPQUEST méthodes. Comme la suggestion de @ Raymond, c'est basé sur la promesse. L'inconvénient est que ce n'est pas complètement supporté dans IE ou Edge.

Si un meilleur support de navigateur est nécessaire, essayez Axios , une bibliothèque client HTTP à la source open source avec beaucoup de support communautaire.


0 commentaires

0
votes

@benjarwar "Inverser votre envoi d'envoi avec la définition onReadyStatechange" Correction du problème d'émission!

Merci @benjarwar et @Raymond pour votre aide. Je vais lire la promesse parce que j'ai passé beaucoup trop de temps à ce sujet.


0 commentaires