как возвратить данные из callback
Вложений: 2
Доброго всем суток. Сам занимаюсь разработкой backend на php. Попросили сделать API. Вроде не сложно. Сделал, решил нормальный скрипт на js написать, с классами, промисами, со структурой в общем (Думал, а че там сложного такого) В итоге споткнулся на callback-ах:)
метод #readHTMLFile(file, back) { let http = new XMLHttpRequest(); if (this.#checkFileExist(file, http)) { http.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) if(back) window.responseCustom = back(this.responseText) } http.open("GET", file, true); http.send(); console.log(window); } else (new API()).ShowError({message: 'Error in reading the file component'}); } я вызываю back функцию, которая дальше идет, и возвращает в ответ промис, который я хочу вернуть из функции. Но как бы я не старался, не могу этого сделать. Я уже и в window - решил записать if(back) window.responseCustom = back(this.responseText) Я вижу, в консоле, что св-во есть (смотри вложения) console.log(window); Но когда пытаюсь напрямую обратиться, то пишет undefined console.log(window.responseCustom); Подскажите пожалуйста в чем проблема может быть |
Мало информации.
Что возвращает метод #checkFileExist? Он синхронный? Цитата:
А что возвращаете, если if(back) ложно? |
Цитата:
#checkFileExist(url, http) { http.open('HEAD', url, false); http.send(); if (http.status === 200) return true; else return false; } #А что возвращаете, если if(back) ложно? я вот как раз над этим думаю. сделал сначала парсинг данных в подключаемые странички, теперь дописываю возврат полученных данных this.#readHTMLFile(filesName, function (filesText) { let virtualDocument = document.implementation.createHTMLDocument("Virtual Document"); virtualDocument.documentElement.innerHTML = filesText; let l = virtualDocument.querySelectorAll(".block-container"); l.length > 0 ? l : (new API()).ShowError({message: 'Error: File is empty'}) //Запрос за данными let pars_meth = (new Parsing(1)).parsing(action); if (typeof pars_meth === 'object') { const API_STAND = new API('fgjfkgjkfjg'); return API_STAND.makeQuery(pars_meth.name, obj => { pars_meth.name = pars_meth.name.replace(/\/api\//i, ''); // Используем Фейкер. ТОЛЬКО ДЛЯ ТЕСТА!!! obj = (new Faker(pars_meth.name, 200)).getDataFaker(); if (obj.status === "error") { (new API()).ShowError({message: obj.data.message}) return false; } Object.keys(obj.data).map(function(message, index) { let h = '.'+pars_meth.name+'_'+message; // console.log(h); // Ищем классы, и заменяем данные let current_el = l[0].querySelector('.'+pars_meth.name+'_'+message); if (current_el !== null) { if (pars_meth.parse === 'li' && (current_el.tagName === 'OL' || current_el.tagName === 'UL') ) { let p = obj.data[message].split(/(\d+)/); obj.data[message] = ''; p.forEach(function (t, i) { if (i % 2 === 0 && i !== 0) { obj.data[message] += "<li>" + t + "</li>"; } }) } current_el.innerHTML = obj.data[message] } }); // Перебираем полученные nodes и вставляем в родительский документ (основной) let AddSection = document.getElementsByClassName('container')[0]; AddSection.innerHTML = ''; [].forEach.call(l, function(item) { AddSection.appendChild(item); }); return obj; }, pars_meth.method); } }); |
Цитата:
Когда вы выполняете 14 console.log(window); там еще не будет responseCustom потому, что onreadystatechange еще не исполнился и присвоения не произошло |
Класс API
class API { constructor(token = '') { this.hasToken = token === '' ? false : true; this.token = token; } async makeQuery(url, nextAction, method = 'GET', data = {}) { try { if(this.hasToken) data.token = this.token; let options = { method: method, headers: { 'Content-Type': 'application/x-www-form-urlencoded', } } /* * Если POST запрос, тогда мы переводим данные в x-www-form-urlencoded и добавляем св-во body * */ if (method === 'POST') { let formBody = []; for (let property in data) { let encodedKey = encodeURIComponent(property); let encodedValue = encodeURIComponent(data[property]); formBody.push(encodedKey + "=" + encodedValue); } formBody = formBody.join("&"); options.body = formBody; } const recieveddata = await fetch(url, options); const result = await recieveddata.json(); return nextAction(result); }catch (error) { return this.ShowError({ message: error }); } } ShowError(data = {}) { Object.keys(data).map(function(message, index) { var value = data[message]; alert(value); }); } } |
Цитата:
|
Так бы этот метод переписать
#readHTMLFile(file, back) { if (!back) // Думаем, что делать, если back не задоно. let http = new XMLHttpRequest(); return new Promise ((res, rej) => { if (this.#checkFileExist(file, http)) { http.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) back(this.responseText).then(t => res(t)) } http.open("GET", file, true); http.send(); // console.log(window); } else { (new API()).ShowError({message: 'Error in reading the file component'}); // Думаем, что возвращать, если ошибка // Можно здесь ничего не выводить, а сразу вернуть // rej ({message: 'Error in reading the file component'}) // и ловить это где то снаружи через try-cath или .catch } }) } |
Спасибо!
|
Часовой пояс GMT +3, время: 22:15. |