Comment synchroniser des fractions d'une Promise ?

Discussion dans 'Développement d'un site Web ou d'une appli mobile' créé par ortolojf, 6 Février 2021.

  1. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 409
    J'aime reçus:
    27
    Bonjour

    Dans une fonction, j'ai une Promise, commençant par :

    Code:
      return new Promise(function(resolve, reject){
       // etc...
     });
    
    
    Cette Promise rend le résultat de la fonction entière, qui est donc asynchrone.

    Je voudrais que certaines parties à l'intérieur de la promise, se terminent avant les autres.

    La Promise rend le résultat par des "resolve(object);"

    Comment faire ?

    Merci beaucoup de votre aide.

    Amicalement.

    PS Bon, je me répond à moi-même : avec des .then

    Obligation de modulariser avec des fonctions pour éviter trop de code.

    Pfffouu... L'Informatique. :)
     
    #1 ortolojf, 6 Février 2021
    Dernière édition: 6 Février 2021
  2. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 409
    J'aime reçus:
    27
    Voilà le résultat de mes efforts. ;)

    J'ai fait 2 classes Javascript, il suffit d'instancier la deuxième classe TEXT, pour lire une url en GET, soit dans le cache, soit directement, avec un contenu toujours à jour.

    Pour celà, je lis/écris un hash code du fichier, que je compare à celui du fichier en cache.

    Cà marche correct.

    Il reste à rajouter du code dans la classe TEXT pour rendre le contenu.

    Voilà le code :

    Code:
    
    const cyrb53 = function(str, seed = 0) {
            let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed;
            for (let i = 0, ch; i < str.length; i++) {
                    ch = str.charCodeAt(i);
                    h1 = Math.imul(h1 ^ ch, 2654435761);
                    h2 = Math.imul(h2 ^ ch, 1597334677);
            }
            h1 = Math.imul(h1 ^ (h1>>>16), 2246822507) ^ Math.imul(h2 ^ (h2>>>13), 3266489909);
            h2 = Math.imul(h2 ^ (h2>>>16), 2246822507) ^ Math.imul(h1 ^ (h1>>>13), 3266489909);
            //    return 4294967296 * (2097151 & h2) + (h1>>>0);
            return (h2>>>0).toString(16).padStart(8,0)+(h1>>>0).toString(16).padStart(8,0);
    };
    
    /**********************************/
    /** CETTE FONCTON REND JSON/TEXT **/
    /**       SUIVANT LE CONTENT-TYPE    **/
    /**            DE LA REPONSE.        **/
    /**********************************/
    const textJson = function(response) {
            return new Promise(function(resolve, reject) {
                    if(response) {
                            var Resp = response.clone();
                            if(Resp.ok) {
                                    if (Resp.headers.get("content-type").match('application/json')) {
                                            Resp.json().then(function(json) {
                                                    resolve(JSON.stringify(json));
                                            }, function(error) {
                                                    reject('1 Error while fetching file : ' + error.message);
                                            })
                                    } else {
                                            Resp.text().then(function(text) {
                                                    resolve(text);
                                            }, function(error) {
                                                    reject('2 Error while fetching file : ' + error.message);
                                            })
                                    }
                            } else {
                                    reject('Error with response Status : ' + Resp.status + ' : ' + Resp.statusText);
                            }
                    } else {
                            reject('Response undefined');
                    }
            });
    };
    
    const from_filename = function(str, sep) {
            return new Array(str.substring(0, str.lastIndexOf(sep)), str.substring(str.lastIndexOf(sep) + 1));
    };
    
    // Small library to improve on fetch() usage
    const api = function(method, url, data, headers = {}){
            return fetch(url, {
                    method: method.toUpperCase(),
                    body: data,                                            // send it as stringified json
                    credentials: api.credentials,                        // to keep the session on the request
                    headers: Object.assign({}, api.headers, headers)    // extend the headers
            }).then(res => res.ok ? Promise.resolve(res) : Promise.reject(res));
    };
    // Defaults that can be globally overwritten
    api.credentials = 'include';
    api.headers = {
            //        'csrf-token': window.csrf || '',     // only if globally set, otherwise ignored
            'mode': 'cors'
            //        'Accept': 'text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8',    // receive text/html
            //        'Content-Type': 'text/html; charset=utf-8'    // send text/html
    };
    // Convenient methods
    ['get', 'post', 'put', 'delete'].forEach(method => {
            api[method] = api.bind(null, method);
    });
    
    const first_promise = function(cache, fileRequest, hash_code_file) {
            var HashCodeResponse    = null;
            var HashCodeCache        = null;
            var Response            = null;
            var Response2            = null;
            console.log('file : ' + fileRequest + ' is being fetched from the cache.');
            return new Promise(function(resolve, reject) {
                    /*****************************************************/
                    /**      ON CHARGE LE HASH CODE DU FICHIER EN CACHE.    **/
                    /*****************************************************/
                    /**        CE HASH CODE DOIT AVOIR ETE UPDATE LORS        **/
                    /**            DU DERNIER CHARGEMENT DU FICHIER.        **/
                    /*****************************************************/
                    cache.match(fileRequest).then(function(response) {
                            if (response) {
                                    Response = response.clone();
                                    Response2 = response.clone();
                                    textJson(Response).then(function(text) {
                                            HashCodeCache = cyrb53(text);
                                            /*****************************/
                                            /**    LE FICHIER DE HASH CODE    **/
                                            /** CONTIENT LE HASH CODE    **/
                                            /**    DU FICHIER CHARGE.        **/
                                            /*****************************/
                                            api['get'](hash_code_file, null,  {'Cache-Control': 'no-store', 'Accept': 'text/plain', 'Content-Type': 'text/plain; charset=utf-8'}).then(function(response) {
                                                    if (response) {
                                                            textJson(response).then(function(text) {
                                                                    HashCodeResponse = text;
                                                                    console.log('Succeded while fetching hash_code_file : ' + hash_code_file + ' with hash code : ' + HashCodeResponse);
                                                                    console.log('Hash code cache = ' + HashCodeCache);
                                                                    console.log('hash code fichier hash_code = ' + HashCodeResponse);
                                                                    if(HashCodeResponse == HashCodeCache) {
                                                                            /**********************/
                                                                            /**    REPONSE DU CACHE **/
                                                                            /**********************/
                                                                            console.log('Response cache = ' + Response2);
                                                                            resolve(Response2);
                                                                    } else {
                                                                            reject('Response cache = false ');
                                                                    }
                                                            }, function(error) {
                                                                    reject('Error while reading file from the cache : ' + fileRequest + '  , with error : ' + error.message);
                                                            })
                                                    } else {
                                                            reject('Empty response while fetching hash code file : ' + hash_code_file);
                                                    }
                                            }, function(error) {
                                                    reject('The hash_code_file : ' + hash_code_file + ' doesn\'t exist, with error : ' + error.message);
                                            })
                                    }, function(error) {
                                            reject('Error while reading file from the cache : ' + fileRequest + '  , with error : ' + error.message);
                                    })
                            } else {
                                    reject('file not in cache : ' + fileRequest);
                            }
                    }, function(error) {
                            reject('file not in cache : ' + fileRequest + '  , with error : ' + error.message);
                    })
            })
    };
    
    const second_promise = function(cache, fileRequest, hash_code_file, requestHeaders) {
            var HashCodeResponse    = null;
            var HashCodeCache        = null;
            var Response            = null;
            var Response2            = null;
            return new Promise(function(resolve, reject) {
                    /*****************************/
                    /**       HASH CODE INVALIDE    **/
                    /**       ON LIT LE FICHIER    **/
                    /**        ET ON UPDATE        **/
                    /**        LE HASH CODE        **/
                    /*****************************/
                    api['get'](fileRequest, null, requestHeaders).then(function(response) {
                            if (response) {
                                    Response = response.clone();
                                    Response2 = response.clone();
                                    textJson(Response).then(function(text) {
                                            HashCodeResponse = cyrb53(text);
                                            console.log('Succeded while fetching file : ' + fileRequest + ' with hash code : ' + HashCodeResponse);
                                            /*************************/
                                            /**      ON MET EN CACHE    **/
                                            /**        LE FICHIER        **/
                                            /*************************/
                                            cache.put(fileRequest, Response).then(function(result) {
                                                    console.log('file : ' + fileRequest + ' set to the cache.');
                                            }, function(error) {
                                                    console.log('file : ' + fileRequest + ' not set in the cache, with error : ' + error.message);
                                            })
                                            /*************************/
                                            /**        ON UPDATE        **/
                                            /**        LE HASH CODE    **/
                                            /*************************/
                                            api['put'](hash_code_file, HashCodeResponse,  {'Cache-Control': 'no-store', 'Accept': 'text/plain', 'Content-Type': 'text/plain; charset=utf-8'}).then(function() {
                                                    console.log('Succeded while uploading hash_code_file : ' + hash_code_file + ' with hash code : ' + HashCodeResponse);
                                            }, function(error) {
                                                    console.log('Error while uploading hash_code_file : ' + hash_code_file + ' with hash code : ' + HashCodeResponse + '  , with error : ' + error.message);
                                            })
                                            /************************/
                                            /**    REPONSE DU FICHIER **/
                                            /************************/
                                            if(Response2 !== null) {
                                                    console.log('Response fichier = ' + Response2);
                                                    resolve(Response2);
                                            } else {
                                                    reject('Response fichier = false');
                                            }
                                    }, function(error) {
                                            reject('Error while fetching file : ' + fileRequest + ' with error : ' + error.message);
                                    })
                            } else {
                                    reject('null response while fetching file : ' + fileRequest);
                            }
                    }, function(error) {
                            reject('Error while fetching file : ' + fileRequest + ' with error : ' + error.message);
                    })
            })
    };
    
    class RESPONSE {
            constructor(request) {
                    const    CACHE = 'pwa-conf-v1';
                    var Request        = null;
                    var fileRequest = null;
                    var file         = null;
                    var accept        = null;
                    var contentType = null;
                    if(typeof request === 'string') {
                            Request = request;
                            fileRequest = request;
                            file = request;
                            accept        = 'text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8';    // receive text/html
                            contentType = 'text/html; charset=utf-8';    // send text/html
                    } else {
                            Request = request.clone();
                            fileRequest = request.clone();
                            tmp_url = new URL(Request.url, location.href);
                            file = tmp_url.pathname;
                            accept        = Request.headers.get("accept");
                            contentType = Request.headers.get("content-type");
                    }
                    var requestHeaders = {
                            'Cache-Control': 'no-store',
                            'Accept': accept,
                            'Content-Type': contentType
                    };
                    var chemin                = null;
                    var avant_file_ndd        = null;
                    var file_ndd            = null;
                    var str                = new Array();
                    var hash_code_file        = null;
                    var intervalId            = null;
                    var waitingResponse        = null;
                    var Response            = null;
                    var Response1            = null;
                    var Response2            = null;
                    var HashCodeResponse    = null;
                    var HashCodeCache        = null;
                    var text                = null;
                    var tmp_text            = null;
                    var hash_code_cache    = null;
                    var hash_code            = null;
                    var contentType        = null;
                    str = from_filename(file, '/');
                    chemin = str[0];
                    avant_file_ndd = from_filename(from_filename(file, '/')[1], '.')[0];
                    file_ndd = from_filename(file, '.')[1];
                    hash_code_file = chemin + '/hash_code_' + avant_file_ndd + '.txt';
                    /*************/
                    /** FICHIER    **/
                    /*************/
                    //                file = new URL(file, location.href);
                    /*****************/
                    /**      FICHIER    **/
                    /**    HASH CODE     **/
                    /*****************/
                    //                hash_code_file = new URL(hash_code_file, location.href);
                    console.log('request for : ' + file + ' and : ' + hash_code_file);
                    return new Promise(function(resolve, reject) {
                            caches.open(CACHE).then(function (cache) {
                                    first_promise(cache, fileRequest, hash_code_file).then(function(response) {
                                            resolve(response);
                                    }).catch(function(error) {
                                            second_promise(cache, fileRequest, hash_code_file, requestHeaders).then(function(response) {
                                                    resolve(response);
                                            }, function(error) {
                                                    reject('Error while reading file : ' + fileRequest + ' , with error : ' + error.message);
                                            })
                                    })
                            }, function(error) {
                                    reject('Error open cache : ' + CACHE + '  , with error : ' + error.message);
                            })
                    })
            }
    }
    
    class TEXT extends RESPONSE {
            constructor(request) {
                    super(request).then(function(response) {
                            console.log('response = ' + response);
                            if (response) {
                                    textJson(response).then(function(text) {
                                            console.log('File return : ' + text);
                                    }, function(error) {
                                            console.log('Empty file while reading file. with error : ' + error.message);
                                    })
                            } else {
                                    console.log('Empty response while reading file.');
                            }
                    }, function(error) {
                            console.log('Empty response while reading file, with error : ' + error.message);
                    })
            }
    }
    
    self.addEventListener('fetch', function(event) {
            // In a real app, you'd use a more sophisticated URL check.
            //        if (event.request.url.match(/.*/)) {
            //        event.respondWith(FETCH(event.request.url));
            var Request = event.request.clone();
            var file = Request.url;
            event.waitUntil(
                    fetch(Request).then(function(response) {
                            if(!response) {
                                    console.log('Response empty FETCHING file : ' + file);
                            }
                            return response;
                    }, function(error) {
                            console.log('Error while FETCHING file, with error : ' + error.message);
                            return false;
                    })
            );
    });
    
    staticAssets = [
            './',
            './index.html',
            './app.js',
            './styles.css'
    ];
    
    function initialize() {
            file = staticAssets[1];
            Text = new TEXT(file);
    }
    /******************************/
    /**    INSTALL APP DEPENDENCIES **/
    /******************************/
    self.addEventListener('install', function(event) {
            console.log('The service worker is being installed.');
            // Bypass the waiting lifecycle stage,
            // just in case there's an older version of this SW registration.
            event.waitUntil(self.skipWaiting());
    });
    //allow sw to control of current page
    /*****************************/
    /**    CLEANUP THE RESOURCES    **/
    /*****************************/
    self.addEventListener('activate', function(event) {
            console.log('Claiming clients for current page');
            // Take control of all pages under this SW's scope immediately,
            // instead of waiting for reload/navigation.
            event.waitUntil(self.clients.claim());
            initialize();
    });
    
    
     
  3. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 409
    J'aime reçus:
    27
    Bonjour

    J'ajoute un brin de code, pour accéder plus facilement aux fichiers :

    Code:
    
    class TEXT extends RESPONSE {
            constructor(request) {
                return super(request).then(function(response) {
                            console.log('response = ' + response);
                            if (response) {
                                    return textJson(response).then(function(text) {
                                            console.log('File return : ');
                                            return text;
                                    }, function(error) {
                                            console.log('Empty file while reading file. with error : ' + error.message);
                                    })
                            } else {
                                    console.log('Empty response while reading file.');
                            }
                    }, function(error) {
                            console.log('Empty response while reading file, with error : ' + error.message);
                    })
            }
    }
    staticAssets = [
            './',
            './index.html',
            './app.js',
            './styles.css'
    ];
    function initialize() {
            file = staticAssets[1];
            new TEXT(file).then(function(text) {
                    if(text) {
                            console.log('Succeded while fetching file : ' + file + '  , with text : ' + text);
                    } else {
                            console.log('Empty file : ' + file + '  , with text : ' + text);
                    }
            }, function(error) {
                    console.log('Error while fetching file, with error : ' + error.message);
            })
    }
    
    
    Faut encore se colleter au .then avec le THEN.

    Celà est dû au caractère asynchrone de la lecture.

    Par rapport à l'algorithme de RESPONSE, on pourrait peut-être envisager autre chose qu'un fichier de hash code par fichier lu. Mais je ne vois pas plus simple.

    On ne peut pas pour ce fichier de hash code, le mettre en cache.

    Par contre, il faudrait peut-être une gestion fiable de leurs emplacements.

    Il y a lieu de gérer les conflits en écriture sur les fichiers eux-mêmes, celà dépendrait de l'implémentation de leur production.

    Merci de me dire si je ne réinvente pas la roue. ;)
     
Chargement...
Similar Threads - synchroniser fractions Promise Forum Date
Synchroniser et partager sur les réseaux sociaux Développement d'un site Web ou d'une appli mobile 13 Novembre 2013