Problème de fonctions synchrone/asynchrone

WRInaute accro
Bonjour

J'ai un léger problème de transmission de données entre deux fonctions synchrones ( LECT() et intialize() ), la première recevant ses données d'une fonction asynchrone ( FETCH() ).

FETCH() fonctionne parfaitement, rend une Promise, et les données sont lues correctement.

Cependant, au début, initialize() rend la chaîne vide ou undefined ( EMPTY() ), alors que les données sont lues après.

Comment lire les données de façon synchrone ou non ?

FETCH(request_file) reçoit en paramètre, une Request ou une url/pathname, et rend une Promise de type Response.

Son rôle est de lire le paramètre dans le cache ou directement, la dernière version du fichier paramètre.

TextJson(response) rend response.text() ou response.json() si valide, en fonction du content-type.

Je dois le peaufiner pour plus de type de response.

Cà marche, mais j'ai besoin d'accéder sans warning à LECT().

Addendum : J'ai fait les déclarations de initialize() et LECT() avant de mettre une Promise dans FETCH(). Je ne crois pas que çà change grand chose.

Merci beaucoup de votre aide.

Voici le code:


JavaScript:
function LECT(Request_File) {
        FETCH(Request_File).then(function(response) {
                if(response === false) {
                        console.log('Failed while reading file, with response : ' + response);
                        return false;
                }
                TextJson(response).then(function(text) {
                        console.log('Succeded while LECTing file : ' + Request_File + ' with text : ' + text);
                        return text;
                }, function(error) {
                        console.log('Error while reading file : ' + Request_File + '  , with error : ' + error.message);
                        return false;
                })
        })
}
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 === false) {
                                console.log('Failed while FETCHING file : ' + file);
                        }
                        return response;
                }, function(error) {
                        console.log('Error while FETCHING file, with error : ' + error.message);
                        return false;
                })
        );
        return false;
});
function initialize() {
        var file = staticAssets[1];
        var text = null;
        text = LECT(file);
        if(!EMPTY(text)) {
                console.log('Succeded while fetching file : ' + file + '  , with text : ' + text);
        } else {
                console.log('Failing while fetching file : ' + file + ' , with response : ' + text);
        }
}
 
Dernière édition:
WRInaute accro
Problème semble-t-il résolu.

J'ai mis un return dans LECT avant le FETCH.

Je vous donne aussi le code de FETCH() :


JavaScript:
      function EMPTY(str) {
        if((typeof str === "undefined")||
                (str === undefined)||
                (str === null)||
                (str === false)||
                (str === '')) {
                return true;
        }
        return false;
}
// 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) ? 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 CACHE = 'pwa-conf-v1';
var staticAssets = [
        './',
        './index.html',
        './app.js',
        './styles.css'
];
function from_filename(str, sep) {
        return new Array(str.substring(0, str.lastIndexOf(sep)), str.substring(str.lastIndexOf(sep) + 1));
}
function TextJson(response) {
        return new Promise(function(resolve, reject) {
                if(EMPTY(response)) {
                        reject(new Error('No Response'));
                }
                var Response = response.clone();
                if(response.ok) {
                        var contentType = Response.headers.get("content-type");
                        if(contentType) {
                                var arrayType = [
                                        'application/json',
                                        'text/html',
                                        'text/plain'
                                ];
                                for(var i = 0; i < arrayType.length; i++) {
                                        if(contentType.match(arrayType[i])) {
                                                break;
                                        }
                                }
                                switch (i) {
                                        case 0 :
                                                resolve(Response.json());
                                                break;
                                        case 1 :
                                        case 2 :
                                                resolve(Response.text());
                                                break;
                                        default :
                                                reject(new Error('Bad Content-Type : ' + contentType));
                                                break;
                                }
                        } else {
                                reject(new Error('No Content-Type'));
                        }
                } else {
                        reject(new Error('Error : Status : ' + Response.status + ' , Type ' + Response.statusText));
                }
        });
}
function FETCH(Request_File) {
        var accept        = null;
        var contentType    = null;
        var Request    = null;
        var file    = null;
        if(typeof Request_File == 'object') {
                Request     = Request_File.clone();
                fileRequest = Request_File.clone();
                var tmp_url = new URL(Request.url, location.href);
                file = tmp_url.pathname;
                accept        = Request_File.headers.get("accept");
                contentType = Request_File.headers.get("content-type");
        } else {
                Request = null;
                fileRequest = Request_File;
                file = Request_File;
                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
        }
        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                    = null;
        var hash_code_file        = 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;
        console.log('Handling FETCH function for : ' + file);
        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) {
                /*************************/
                /**    VALEURS IMPOSSIBLES    **/
                /*************************/
                HashCodeResponse    = null;
                HashCodeCache        = null;
                caches.open(CACHE).then(function (cache) {
                        /*****************************************************/
                        /**    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 (!EMPTY(response)) {
                                        Response = response.clone();
                                        TextJson(response).then(function(text) {
                                                if(EMPTY(text)) {
                                                        cache.delete(fileRequest).then(function(result) {
                                                                console.log('file : ' + fileRequest + ' deleted from the cache.');
                                                        }, function(error) {
                                                                console.log('file : ' + fileRequest + ' not in the cache, with error : ' + error.message);
                                                        })
                                                } else {
                                                        HashCodeCache = forge_sha256(text);
                                                }
                                        }, function(error) {
                                                console.log('file not in cache : ' + fileRequest + '  , with error : ' + error.message);
                                        })
                                } else {
                                        console.log('file not in cache : ' + fileRequest);
                                }
                        }, function(error) {
                                console.log('file not in cache : ' + fileRequest + '  , with error : ' + error.message);
                        })
                        /*****************************/
                        /**    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) {
                                TextJson(response).then(function(text) {
                                        HashCodeResponse = text;
                                        console.log('Succeded while fetching hash_code_file : ' + hash_code_file + ' with hash code : ' + HashCodeResponse);
                                        console.log('HashCodeCache = ' + HashCodeCache);
                                        console.log('HashCodeResponse = ' + HashCodeResponse);
                                        if(HashCodeResponse !== null &&
                                                HashCodeCache !== null &&
                                                HashCodeResponse == HashCodeCache) {
                                                /**********************/
                                                /**    REPONSE DU CACHE **/
                                                /**********************/
                                                resolve(Response);
                                        }
                                }, function(error) {
                                        console.log('Error while reading hash_code_file : ' + hash_code_file + '  , with error : ' + error.message);
                                })
                        }, function(error) {
                                console.log('The hash_code_file : ' + hash_code_file + '  , doesn\'t exist');
                        })
                        /*****************************/
                        /**       HASH CODE INVALIDE    **/
                        /**       ON LIT LE FICHIER    **/
                        /**        ET ON UPDATE        **/
                        /**        LE HASH CODE        **/
                        /*****************************/
                        api['get'](fileRequest, null, requestHeaders).then(function(response) {
                                Response1 = response.clone();
                                Response2 = response.clone();
                                TextJson(response).then(function(text) {
                                        HashCodeResponse = forge_sha256(text);
                                        console.log('Succeded while fetching file : ' + fileRequest + ' with hash code : ' + HashCodeResponse);
                                        /*************************/
                                        /**      ON MET EN CACHE    **/
                                        /**        LE FICHIER        **/
                                        /*************************/
                                        cache.put(fileRequest, Response1).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 **/
                                        /************************/
                                        resolve(Response2);
                                }, function(error) {
                                        reject('Error while reading file : ' + fileRequest + '  , with error : ' + error.message);
                                })
                        }, function(error) {
                                reject('Error while fetching file : ' + fileRequest + '  , with error : ' + error.message);
                        })
                }, function(error) {
                        reject('Error open cache : ' + CACHE + '  , with error : ' + error.message);
                })
        });
}
async function LECT(Request_File) {
        return fetch(Request_File).then(function(response) {
                if(EMPTY(response)) {
                        console.log('Failed while reading file, with response : ' + response);
                        return false;
                }
                TextJson(response).then(function(text) {
                        console.log('Succeded while LECTing file : ' + Request_File + ' with text : ' + text);
                        return text;
                }, function(error) {
                        console.log('Error while reading file : ' + Request_File + '  , with error : ' + error.message);
                        return false;
                })
              
        }, function(error) {
                console.log('Error while FETCHING file : ' + Request_File + '  , with error : ' + error.message);
                return false;
        })
              
        console.log('Succeded while LECTing file : ' + Request_File + ' with Text : ' + Text);
}
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(EMPTY(response)) {
                                console.log('Response empty FETCHING file : ' + file);
                        }
                        return response;
                }, function(error) {
                        console.log('Error while FETCHING file, with error : ' + error.message);
                        return false;
                })
        );
});
function initialize() {
        var file = staticAssets[1];
        var text = null;
        text = LECT(file);
        if(!EMPTY(text)) {
                console.log('Succeded while fetching file : ' + file + '  , with text : ' + text);
        } else {
                console.log('Failing while fetching file : ' + file + ' , with response : ' + text);
        }
}
/******************************/
/**    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();
});
 
WRInaute accro
Maintenant j'ai un problème.

Une classe RESPONSE rend une Promise avec
(response) si succès, reject(newError('')) si échec.

Je reçois la response dans la classe TXT ci-dessous.

Cà ne marche pas, indique qu'une propriété CACHE de RESPONSE est undefined.

Faut-il faire un extend de RESPONSE vers TEXT, pour que TEXT hérite de RESPONSE ?

Merci beaucoup de votre aide.



JavaScript:
class TEXT {
        EMPTY(str) {
                if((typeof str === "undefined")||
                        (str === undefined)||
                        (str === null)||
                        (str === false)||
                        (str === '')) {
                        return true;
                }
                return false;
        }
        constructor(request) {
                if(typeof request == 'object') {
                        this.Request = request.clone();
                } else {
                        this.Request = request;
                }
                console.log('Trying to read file : ' + this.Request);
                this.Text = null;
                new RESPONSE(this.Request).then(response) {
                        this.Text = TextJson(response);
                        if(!this.EMPTY(this.Text)) {
                                this.Text = text;
                                console.log('Succeded while reading file, with text : ' + this.Text);
                                return this.Text;
                        } else {
                                console.log('Error while reading file, with error : ' + error.message);
                                return false;
                        }
                }, function(error) {
                        console.log('Error while Fetching file, with error : ' + error.message);
                        return false;
                })
        }
}
 
WRInaute accro
Bonjour

Je me débat depuis 5 jours sur deux classes Javascript.

RESPONSE rend une Promise sous la forme d'une Response.

hash64() est la fonction de hash de RESPONSE.

La fonction TextJson(response) rend aussi une Promise de type texte ou json, suivant le http_header de retour.

La classe fille de RESPONSE, TEXT, utilise TextJson(response), mais TEXT est censé rendre le contenu texte du fichier lu.

L'intérêt est de modulariser/optimiser les fetch, car le constructeur ( non présent ) de RESPONSE rend systématiquement la version à jour du fichier distant, en cache éventuellement.

Le message d'erreur, indique qu'un constructeur de classe dérivée, doit obligatoirement rendre un object ou undefined.

Moi, je veux une string ( contenu du fichier ).

Que changer dans le code ?

Merci.


JavaScript:
class RESPONSE {
        hash32(str) {
                var hash = 0, i, chr;
                for (i = 0; i < str.length; i++) {
                        chr   = str.charCodeAt(i);
                        hash  = ((hash << 5) - hash) + chr;
                        hash |= 0; // Convert to 32bit integer
                }
                return hash;
        }
        hash64(str) {
                var h1 = this.hash32(str);  // returns 32 bit (as 8 byte hex string)
                return h1 + this.hash32(h1 + str);  // 64 bit (as 16 byte hex string)
        }
        EMPTY(str) {
                if((typeof str === "undefined")||
                        (str === undefined)||
                        (str === null)||
                        (str === false)||
                        (str === '')) {
                        return true;
                }
                return false;
        }
        TextJson(response) {
                return new Promise(function(resolve, reject) {
                        if(this.EMPTY(response)) {
                                reject('No Response');
                        } else {
                                this.Res = response.clone();
                                if(response.ok) {
                                        var contentType = this.Res.headers.get("content-type");
                                        if(contentType) {
                                                var arrayType = [
                                                        'application/json',
                                                        'text/html',
                                                        'text/plain'
                                                ];
                                                for(var i = 0; i < arrayType.length; i++) {
                                                        if(contentType.match(arrayType[i])) {
                                                                break;
                                                        }
                                                }
                                                switch (i) {
                                                        case 0 :
                                                                resolve(this.Res.json());
                                                                break;
                                                        case 1 :
                                                        case 2 :
                                                                resolve(this.Res.text());
                                                                break;
                                                        default :
                                                                reject('Bad Content-Type : ' + contentType);
                                                                break;
                                                }
                                        } else {
                                                reject('No Content-Type');
                                        }
                                } else {
                                        reject('Error : Status : ' + Response.status + ' , Type ' + Response.statusText);
                                }
                        }
                }, function(error) {
                        reject('Error while receiving  response from file, with error : ' + error.message);
                })
        }
}

class TEXT extends RESPONSE {
        constructor(request) {
                //                Object.setPrototypeOf(TEXT, RESPONSE);
                super(request);
                if(!this.Response) {
                        console.log('Empty response while reading file : ' + request);
                        return false;
                }
                return this.TextJson(this.Response).then(function(text) {
                        if(!this.EMPTY(text)) {
                                this.Text = text;
                                console.log(this.Text);
                                return this.Text;
                        } else {
                                console.log('Empty file : ' + this.Response);
                                return false;
                        }
                }, function(error) {
                        reject('Empty file : ' + this.Response);
                        return false;
                })
        }
        getText() {
                return this.Text;
        }
}
staticAssets = [
        './',
        './index.html',
        './app.js',
        './styles.css'
];
function initialize() {
        file = staticAssets[1];
        text = new TEXT(file).getText();
        console.log('Succeded while fetching file : ' + file + '  , with text : ' + text);
}
 
Discussions similaires
Haut