synchroniser des r=c3=a9ponses asynchrones =3f=3f=3f

1 réponse
Avatar
Une B=c3=a9vue
J'ai une appli qui demande à un serveur websocket des données telles que
albums, cameras et persons.

les réponses sont asynchrones et les request sont "bêtement" à la
"queue-leu-leu" (ES6):

let requestAlbums = {database: 'photos', collection: 'albums',
mode: 'read', sort: {startdate: 1, stopdate: 1}};
this.props.socket.sendRequest(requestAlbums, (message) => {
this.setState({albums: message.results.albums});
});
let requestCameras = {database: 'photos', collection: 'cameras',
mode: 'read', sort: {make: 1, model: 1}};
this.props.socket.sendRequest(requestCameras, (message) => {
this.setState({cameras: message.results.cameras});
});
let requestPersons = {database: 'photos', collection: 'persons',
mode: 'read', sort: {lastname: 1, firstname: 1}};
this.props.socket.sendRequest(requestPersons, (message) => {
this.setState({persons: message.results.persons});
});


je voudrais donc n'avoir à faire qu'une seul "this.setState({...})" commun :

this.setState({
albums: message.results.albums,
cameras: message.results.cameras,
persons: message.results.persons
});

pour cela il faudrait, en quelque sorte, mémoriser les résultats
'albums' et 'cameras' en attendant que les résultats 'persons' arrivent.

est-ce possible en chaînant des "promises" ?

1 réponse

Avatar
Une B=c3=a9vue
Le 16/04/2017 à 08:39, Une Bévue a écrit :
est-ce possible en chaînant des "promises" ?

oui, j'ai simulé deux solutions avec des Promises :
solution promise.then(...)
var albumsMethod = function() {
var promise = new Promise(function(resolve, reject){
setTimeout(function() {
data.albums = {delay: ((new Date()).getTime() -
start), message: '« albumsMethod » completed'};
console_info('data:n' + JSON.stringify(data, null, 2));
resolve(data);
}, 500);
});
return promise;
};
var camerasMethod = function(someStuff) {
var promise = new Promise(function(resolve, reject){
setTimeout(function() {
data.cameras = {delay: ((new Date()).getTime() -
start), message: '« camerasMethod » completed'};
console_info('data:n' + JSON.stringify(data, null, 2));
resolve(data);
}, 400);
});
return promise;
};
var locationsMethod = function(someStuff) {
var promise = new Promise(function(resolve, reject){
setTimeout(function() {
data.locations = {delay: ((new Date()).getTime() -
start), message: '« locationsMethod » completed'};
console_info('data:n' + JSON.stringify(data, null, 2));
resolve(data);
}, 300);
});
return promise;
};
var personsMethod = function(someStuff) {
var promise = new Promise(function(resolve, reject){
setTimeout(function() {
data.persons = {delay: ((new Date()).getTime() -
start), message: '« personsMethod » completed'};
console_info('data:n' + JSON.stringify(data, null, 2));
resolve(data);
}, 200);
});
return promise;
};
albumsMethod().then(camerasMethod).then(locationsMethod).then(personsMethod);
solution Promise.all(...)
var promises = [];
var albumsPromise = new Promise(function(resolve, reject){
setTimeout(function() {
var albums = {delay: ((new Date()).getTime() - start),
message: '« albumsPromise » resolved'};
var albums_id = '9876543210';
resolve({albums: albums, albums_id: albums_id});}, 1000);
});
promises.push(albumsPromise);
var camerasPromise = new Promise(function(resolve, reject){
setTimeout(function() {
var cameras = {delay: ((new Date()).getTime() - start),
message: '« camerasPromise » resolved'};
resolve({cameras: cameras});}, 500);
});
promises.push(camerasPromise);
var locationsPromise = new Promise(function(resolve, reject){
setTimeout(function() {
var locations = {delay: ((new Date()).getTime() - start),
message: '« locationsPromise » resolved'};
resolve({locations: locations});}, 1500);
});
promises.push(locationsPromise);
var personsPromise = new Promise(function(resolve, reject){
setTimeout(function() {
var persons = {delay: ((new Date()).getTime() - start),
message: '« personsPromise » resolved'};
var persons_id = '0123456789';
resolve({persons: persons, persons_id: persons_id});}, 100);
});
promises.push(personsPromise);
Promise.all(promises).then(function(datas) {
var data = {};
for (var i = 0, l = datas.length; i < l; i++) {
for (var prop in datas[i]) {
data[prop] = datas[i][prop];
}
}
console_info(((new Date()).getTime() - start) + ' - data:n'
+ JSON.stringify(data, null, 2));
});
j'obtiens ce que je recherche :
1501 - data:
{
"albums": {
"delay": 1005,
"message": "« albumsPromise » resolved"
},
"albums_id": "9876543210",
"cameras": {
"delay": 502,
"message": "« camerasPromise » resolved"
},
"locations": {
"delay": 1501,
"message": "« locationsPromise » resolved"
},
"persons": {
"delay": 104,
"message": "« personsPromise » resolved"
},
"persons_id": "0123456789"
}
mais avec #all je dois "mettre à plat" l'array de résultats retournés.
testé sur websocket...