Implementer async/await

L’auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Salut, ça fait quelques jours que je bloque sur un problème. C’est une fonction qui sert seulement à envoyer une requête vers openweathermap.com pour afficher des infos comme la température, vitesse du vent, humidité… d’une ville. C’est tout simple, la voilà :^

// Le ficher 'nearby.js'

// La fonction remove_accents() enleve les accents ex: bléblé -> bleble | développement -> developpement

// J'utilise le module 'request' pour envoyer une requête http

module.exports = function find_temp(url) {
        if (url === undefined) { throw new Error('No argument passed.'); }
    
        const formatedURL = remove_accents(url);
    
        console.log('Sent: ' + formatedURL);
        
        request(url, (error, response, body) => {
            
            if (error) {console.log('error at request'); console.log(error);}
            
            const obj  = JSON.parse(body);
    
            if (obj.message == 'city not found'){ console.log('city not found'); }
    
            try {
    
                const DATA = {
                    tempe_2: Math.round(obj.main.temp) || null
                };
                
                console.log(DATA.tempe_2); // Retourne la température, pas de undefined
                return DATA.tempe_2;

            } catch (error) {
                console.log('Cannot read obj.main.temp (tempe_2) proprety.');
                console.log(error);
            }
        });
    }

..

// Fichier 'weather.js'

// ...
// NEARBY_CITIES.f2.name est le nom d'une ville ex: Paris, Moscow..

const url2 = 'http://api.openweathermap.org/data/2.5/weather?q=' + NEARBY_CITIES.f2.name +
                    '&units=metric&appid=' + apiKey; 
                   
                    let i = find_temp(url2);
                    console.log(i) // undefined
// ...

'console.log' retourne undefined. Plus exactement :

Sent: http://api.openweathermap.org/data/2.5/weather?q=Le Pre-Saint-Gervais&units=metric&appid=APIKEY
city not found
Cannot read obj.main.temp (tempe_2) proprety.
TypeError: Cannot read property 'temp' of undefined
    at Request.request [as _callback] (C:\Users\AdminHP\Desktop\Python\wind\nearby.js:62:35)
    at Request.self.callback (C:\Users\AdminHP\Desktop\Python\wind\node_modules\request\request.js:185:22)
    at Request.emit (events.js:182:13)
    at Request.<anonymous> (C:\Users\AdminHP\Desktop\Python\wind\node_modules\request\request.js:1157:10)
    at Request.emit (events.js:182:13)
    at IncomingMessage.<anonymous> (C:\Users\AdminHP\Desktop\Python\wind\node_modules\request\request.js:1079:12)
    at Object.onceWrapper (events.js:273:13)
    at IncomingMessage.emit (events.js:187:15)
    at endReadableNT (_stream_readable.js:1081:12)
    at process._tickCallback (internal/process/next_tick.js:63:19)

Si j’envois la requête manuellement (par navigateur), ça marche. Résultat pour "Le Pre-Saint-Gervais":

{"coord":{"lon":2.4,"lat":48.89},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01n"}],"base":"stations","main":{"temp":16.74,"pressure":1019,"humidity":72,"temp_min":15,"temp_max":19},"visibility":10000,"wind":{"speed":2.1,"deg":360},"clouds":{"all":0},"dt":1534372200,"sys":{"type":1,"id":5610,"message":0.0041,"country":"FR","sunrise":1534308245,"sunset":1534359860},"id":3002499,"name":"Le Pre-Saint-Gervais","cod":200}

J’ai recherché une réponse et je pense que la solution serait d’implementer async/await ou des promises stackoverflow. Est-ce que quelqu’un pourrait me monter comment implémenter ça ? Merci

Édité par PixarFilmz-

+0 -0

Salut, ça fait quelques jours que je bloque sur un problème. C’est une fonction qui sert seulement à envoyer une requête vers openweathermap.com et ensuite afficher la température, vitesse vent, humidité.. C’est tout simple, la voilà :

sad

PixarFilmz-

Salut,

ça va être difficile de t’aider si tu ne donnes ni ton problème, ni ce que tu as essayé de faire. ;)

+1 -0
Auteur du sujet

Salut, ça fait quelques jours que je bloque sur un problème. C’est une fonction qui sert seulement à envoyer une requête vers openweathermap.com et ensuite afficher la température, vitesse vent, humidité.. C’est tout simple, la voilà :

sad

PixarFilmz-

Salut,

ça va être difficile de t’aider si tu ne donnes ni ton problème, ni ce que tu as essayé de faire. ;)

unidan

J’ai envoyé sans avoir fini.. Mon erreur :(

Édité par PixarFilmz-

+0 -0

Effectivement :P

Le problème, c’est que tu fais un return dans le code de la fonction que tu passes à request mais que tu ne fais pas de return dans le code de ta fonction. Selon si request est asynchrone tu dois soit retourner une promesse et la résoudre dans ta fonction passée à request, soit retourner la valeur retournée par request.

Pour l’implémentation, je ne sais pas ce que supporte request, mais tu peux toujours promessifier si besoin. Dans ton cas une solution synchrone serait quand même bien plus simple.

Édité par unidan

+1 -0
Auteur du sujet

Effectivement :P

Le problème, c’est que tu fais un return dans le code de la fonction que tu passes à request mais que tu ne fais pas de return dans le code de ta fonction. Selon si request est asynchrone tu dois soit retourner une promesse et la résoudre dans ta fonction passée à request, soit retourner la valeur retournée par request.

Je ne comprend pas très bien ce que tu dis ici ?

Pour l’implémentation, je ne sais pas ce que supporte request, mais tu peux toujours promessifier si besoin. Dans ton cas une solution synchrone serait quand même bien plus simple.

unidan

Comment implémenter la solution synchrone ?

+0 -0
Auteur du sujet

En effet, le module request ne retourne pas de Promise. J’ai trouvé ce module request-promise qui retourne des Promises.

En fin de compte, ça donne:

let a = request-promise(monURL)
.then((response) => {
                       
    const obj = JSON.parse(response);
    console.log('>> ' + obj.name);
                        
    return new Promise( (resolve, reject) => {
        resolve(obj.name);
     });
})
                    
a.then((x) => {
    console.log(x) // marche :)
})

J’ai besoin d’utiliser ça dans une fonction mais à chaques essais, l’erreur Cannot read property 'then' of undefined revient :

// Request
function request-promise-fonction(url) {
    if (url === undefined) { throw new Error('No argument passed.'); }

    const formated_url = removeAccents(url);

    const options = {
        uri: formated_url,
    };
    
    console.log('Sent: ' + options.uri);

    request-promise(options)
    .then((response) => {
        const obj = JSON.parse(response);
        console.log('HERE!! ' + obj.name);

        return new Promise( (resolve, reject) => {
            resolve(obj.name);
        });

    }).catch((error) => {
        console.log('Error :(');
        return null;
    })
}

.....

let a = request-promise-fonction(monURL);

a.then((x) => {
    console.log(x); // Cannot read property 'then' of undefined
}

Dans le premier example, la façon que j’utilise pour sauvegarder ce qui est affiché est d’utilisé un tableau, est-ce une bonne façon de faire ?

// ...

const array = [];

a.then((x) => {
    // ..
    array.push(x);
})

delay(5000).then(() => {
    console.log(array[0]); // Affiche bien le contenus de 'x'
})

// ...
+0 -0

Cette réponse a aidé l’auteur du sujet

Salut !

Plusieurs remarques :

  1. request-promise et request-promise-fonction ne sont pas des noms valides en JS. Tu ne peux pas avoir de - dans un nom de variable. Tu devrais t’en être aperçu parce que ça cause immédiatement une erreur de syntaxe : Uncaught SyntaxError: Unexpected token -

  2.             if (obj.message == 'city not found'){ console.log('city not found'); }
    
                try {
    
                    const DATA = {
                        tempe_2: Math.round(obj.main.temp) || null
                    };
    

    C’est pas une bonne idée du tout ça. Si la ville n’est pas trouvée, pourquoi continuer et essayer quand même de lire obj.main.temp alors que comme tu l’as déjà établi obj n’a pas de propriété main quand la ville n’est pas trouvée ?

    (Cherche l’erreur de logique dans ceci : Ouvre le frigo, s’il n’y a pas d’oeufs dedans crie "Il n’y a pas d’oeufs !", ensuite prends les oeufs dans le frigo et fais une omelette.)

  3. const array = [];
    
    a.then((x) => {
        // ..
        array.push(x);
    })
    
    delay(5000).then(() => {
        console.log(array[0]); // Affiche bien le contenus de 'x'
    })
    

    Attention ! Tu ne sais pas quand a sera résolu. Ça peut très bien prendre plus de 5000ms. Ta feinte avec l’array fonctionne mais est inutile. Tu peux simplement retourner x ou retourner une promesse qui résout avec x.

  4. Lis quelques articles sur comment les promesses fonctionnent, puis lis quelques articles sur async/await. Expérimente ce que tu penses avoir compris. Après si t’as des questions, on pourra y répondre.

Édité par cepus

Vous aimez le frontend ? Il y a un tas de petites tâches faciles si vous voulez contribuer à ZdS : https://github.com/zestedesavoir/zds-site/issues?q=is%3Aissue+is%3Aopen+label%3AC-Front

+2 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte