11487 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

Comme tout le monde j’essaie de combler mes lacunes en javascript ES-next et en ce moment je m'intéresse aux promises.

Je voudrais savoir quelle est la relation ou les différences) entre Ajax httpRequest et les nouvelles fonctionnalités de promises en Javascript..
Bonjour Lionel,

Il me semble que xhr est remplacé petit à petit par les promises (avec async await et ensuite avec fetch).
Modérateur
Les promesses sont la solution aux problèmes asynchrone : tu reçois (ou pas) l'information/résultat via une methode de callback .
Les promesses sont la solution à tout. Hélas, elles n'engagent que ceux qui y croient.
Modérateur
Hello, à priori il n'y a aucun rapport. On peut s'amuser à écrire une fonction qui englobe XmlHTTPRequest et qui gère les promises, mais ce n'est pas dans la norme de base, exemple (repris de https://gomakethings.com/promise-based-xhr/ ):

var makeRequest = function (url, method) {

	// Create the XHR request
	var request = new XMLHttpRequest();

	// Return it as a Promise
	return new Promise(function (resolve, reject) {

		// Setup our listener to process compeleted requests
		request.onreadystatechange = function () {

			// Only run if the request is complete
			if (request.readyState !== 4) return;

			// Process the response
			if (request.status >= 200 && request.status < 300) {
				// If successful
				resolve(request);
			} else {
				// If failed
				reject({
					status: request.status,
					statusText: request.statusText
				});
			}

		};

		// Setup our HTTP request
		request.open(method || 'GET', url, true);

		// Send the request
		request.send();

	});
};


Sinon le futur est dans fetch, qui va remplacer XHR en intégrant les promises, mais c'est encore expérimental. On peut faire des requêtes très simples:


fetch('/api/truc.json')
  .then(function(response) {
      return response.json();
  })
  .then(function(data) {
      alert(data.message);
  });


On en passant plus de paramètres, et en usant des objets Headers, Response, Request, FormData, etc.
Modérateur
kustolovic a écrit :

....
Sinon le futur est dans fetch, qui va remplacer XHR en intégrant les promises, mais c'est encore expérimental.
....


le futur ? Fetch, tu peux l'utiliser déjà. Je l'utilise depuis pas mal de temps maintenant. Smiley smile
Modérateur
Tu fais ce que tu veux, mais utiliser une spec pas encore stabilisée, dont le support est encore partiel (entre 50% et 90% des visites selon les sites que je gère), pour une spec qui n'apporte qu'un confort d'écriture, mais sans possibilité fonctionnelle supplémentaire, je considère que c'est du futur pour de la prod.
Modifié par kustolovic (28 Nov 2019 - 09:36)
Bonjour,
C'est vrai je me suis mal exprimé, mea culpa. Les promises utilisent egalement xhr (Xml Http Request).
J ai pensé faire une petite demo des évolutions d'AJAX , mais en très très basique (je ne traite pas des erreurs ...). Je me suis inspiré d'un tuto de Grafikart que j'avais vu il y a un certain temps (rendons à César...).
On fait un GET sur un fichier 'users.json' et on affiche de 2 facons : 'affiche1' affiche la reponse brute (donc string) et 'affiche2' affiche après avoir transformé la reponse brute en objet (grace à parse.Json).
Par contre pour 'await async', la demo ne s'y prete pas.

<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>1. xhr</title>
    <style>
        body{font-size: 1.1em;}
        h1{font-size: 1.2em;}
    </style>
</head>
<body>

    <h1> 1. Affichage des donnees brutes (string) de 'xhr.responseText' :</h1>
    <div id="show1"></div>
    
    <h1> 2. Affichage après que 'xhr.responseText' soit devenu objet :</h1>
    <div id="show2"></div>


     <script src="z01_initial.js"></script>   
    <!-- <script src="z02_callback.js"></script> --> 
    <!-- <script src="z03_promise.js"></script>  -->
    <!-- <script src="z04_await.js"></script>    -->
    <!-- <script src="z05_fetch.js"></script>    --> 

</body>
</html>
users.json


[
  {
    "id": 1,
    "nom": "BRENIL",
    "prenom": "Georges",
    "email": "bg@citron.fr",
    "adresse": {
      "rue": "rue de Paris",
      "ville": "Agen",
      "cp": "47000",
      "gps": {
        "lat": "-12.2525",
        "lng": "57.6284"
      }
    },
    "telephone": "01 11 11 11 11"
  },
  {
    "id": 2,
    "nom": "FRECHON",
    "prenom": "Damien",
    "email": "fd@hal.fr",
    "adresse": {
      "rue": "bd Victor Hugo",
      "ville": "Bordeaux",
      "cp": "33000",
      "gps": {
        "lat": "-57.8585",
        "lng": "-52.4658"
      }
    },
    "telephone": "01 12 12 12 12"
  },
  {
    "id": 3,
    "nom": "GIRO",
    "prenom": "Elisabeth",
    "email": "ge@liberty.fr",
    "adresse": {
      "rue": "route d'Olivet",
      "ville": "Orleans",
      "cp": "45000",
      "gps": {
        "lat": "-53.2538",
        "lng": "-26.9654"
      }
    },
    "telephone": "01 13 13 13 13"
  }
]
z01_initial.js

function affiche1(reponse){
    let show1 = document.getElementById('show1');
    show1.innerHTML = reponse;
}

function affiche2(reponse){
    let users = JSON.parse(reponse); // users = obj.
    let show2 = document.getElementById('show2');
        for(let $cle1 in users){
            show2.innerHTML+= $cle1 + '<br>';
            for(let $cle2 in users[$cle1]){
                show2.innerHTML+= '<b>'+ $cle2 + '</b> : ';
                if(typeof users[$cle1][$cle2]=='object'){
                    show2.innerHTML += '<br>';
                    for(let $cle3 in users[$cle1][$cle2]){
                        show2.innerHTML+= ' ' + $cle3 + ' : ';
                        if(typeof users[$cle1][$cle2][$cle3]=='object'){
                            for(let $cle4 in users[$cle1][$cle2][$cle3]){
                                show2.innerHTML+= users[$cle1][$cle2][$cle3][$cle4] + ' ; ';
                            }
                            show2.innerHTML+='<br>';
                        } else {show2.innerHTML+= users[$cle1][$cle2][$cle3] + '<br>';}
                    }
                } else {show2.innerHTML+= users[$cle1][$cle2] + '<br>';}
            } 
            show2.innerHTML+='</br>';
        }
}
// ----- 

function get(url){
    let xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function(){ 
        if(xhr.readyState===4){ 
            if(this.status===200){

                reponse = xhr.responseText;  // response = string
                    affiche1(reponse);
                    affiche2(reponse);
                
            } else {console.log('erreur'+ xhr);}
        }        
    }
    xhr.open('GET', url, true); 
    xhr.send();
}
// ******.


get('users.json');
z02_callback.js
 
function affiche1(reponse){
  ... idem 
}
function affiche2(reponse){
  ... idem
}
// ----- 

function get(url, success){
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function(){
        if(xhr.readyState===4){
            if(this.status===200){
            
                reponse = xhr.responseText; 
                success(reponse);
                   
            } else {console.log('erreur'+ xhr);}
        }        
    }
    xhr.open('GET', url, true); 
    xhr.send(); 
}
// *******************

get('users.json', function(reponse){
    affiche1(reponse);
    affiche2(reponse);
});
z03_promise.js

function affiche1(reponse){
}
function affiche2(reponse){
}
// ----- 

function get(url){
    return new Promise(function(resolve){
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function(){
        if(xhr.readyState===4){
            if(this.status===200){

                let reponse = xhr.responseText;
                resolve(reponse);
            
            } else {console.log('erreur'+ xhr);}
        }        
    }
    xhr.open('GET', url, true);
    xhr.send();
    });
}
// **************

get('users.json').then(function(reponse){
    affiche1(reponse);
    affiche2(reponse);
}).then(function(){
    alert('Fin de la requete AJAX');
}).then(function(){
    alert('exemple des enchainements des promises');
});
z05_fetch.js

function affiche1(reponse){
}

function affiche2(reponse){      
}
// ----- 

async function get(url){
    try{
        let response = await fetch(url) // renvoie une promise
        if(response.ok){
            let reponse = await response.text() 
            affiche1(reponse);
            affiche2(reponse);
        } else{console.log('erreur'+ xhr);}
    } catch(e){
        console.log(e);
    }
}

get('users.json')
Ces 4 fichiers JS renvoie le meme resultat :

 1. Affichage des donnees brutes (string) de 'xhr.responseText' :
[ { "id": 1, "nom": "BRENIL", "prenom": "Georges", "email": "bg@citron.fr", "adresse": { "rue": "rue de Paris", "ville": "Agen", "cp": "47000", "gps": { "lat": "-12.2525", "lng": "57.6284" } }, "telephone": "01 11 11 11 11" }, { "id": 2, "nom": "FRECHON", "prenom": "Damien", "email": "fd@hal.fr", "adresse": { "rue": "bd Victor Hugo", "ville": "Bordeaux", "cp": "33000", "gps": { "lat": "-57.8585", "lng": "-52.4658" } }, "telephone": "01 12 12 12 12" }, { "id": 3, "nom": "GIRO", "prenom": "Elisabeth", "email": "ge@liberty.fr", "adresse": { "rue": "route d'Olivet", "ville": "Orleans", "cp": "45000", "gps": { "lat": "-53.2538", "lng": "-26.9654" } }, "telephone": "01 13 13 13 13" } ]
2. Affichage après que 'xhr.responseText' soit devenu objet :
0
id : 1
nom : BRENIL
prenom : Georges
email : bg@citron.fr
adresse :
rue : rue de Paris
ville : Agen
cp : 47000
gps : -12.2525 ; 57.6284 ;
telephone : 01 11 11 11 11

1
id : 2
nom : FRECHON
prenom : Damien
email : fd@hal.fr
adresse :
rue : bd Victor Hugo
ville : Bordeaux
cp : 33000
gps : -57.8585 ; -52.4658 ;
telephone : 01 12 12 12 12

2
id : 3
nom : GIRO
prenom : Elisabeth
email : ge@liberty.fr
adresse :
rue : route d'Olivet
ville : Orleans
cp : 45000
gps : -53.2538 ; -26.9654 ;
telephone : 01 13 13 13 13