07.12.2020, 15:31
|
Аспирант
|
|
Регистрация: 05.04.2018
Сообщений: 77
|
|
как возвратить данные из callback
Доброго всем суток. Сам занимаюсь разработкой 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);
Подскажите пожалуйста в чем проблема может быть
Последний раз редактировалось SolomonRei, 07.12.2020 в 15:34.
|
|
07.12.2020, 15:57
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,744
|
|
Мало информации.
Что возвращает метод #checkFileExist? Он синхронный?
Сообщение от SolomonRei
|
я вызываю back функцию, которая дальше идет, и возвращает в ответ промис, который я хочу вернуть из функции.
|
А что вы возвращаете, когда #checkFileExist не срабатывает?
А что возвращаете, если if(back) ложно?
|
|
07.12.2020, 16:02
|
Аспирант
|
|
Регистрация: 05.04.2018
Сообщений: 77
|
|
Сообщение от voraa
|
Мало информации.
Что возвращает метод #checkFileExist? Он синхронный?
А что вы возвращаете, когда #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);
}
});
|
|
07.12.2020, 16:03
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,744
|
|
Сообщение от SolomonRei
|
Я вижу, в консоле, что св-во есть (смотри вложения)
console.log(window);
Но когда пытаюсь напрямую обратиться, то пишет undefined
console.log(window.responseCustom);
|
В какой момент вы смотрите?
Когда вы выполняете
14 console.log(window);
там еще не будет responseCustom потому, что onreadystatechange еще не исполнился и присвоения не произошло
|
|
07.12.2020, 16:04
|
Аспирант
|
|
Регистрация: 05.04.2018
Сообщений: 77
|
|
Класс 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);
});
}
}
|
|
07.12.2020, 16:05
|
Аспирант
|
|
Регистрация: 05.04.2018
Сообщений: 77
|
|
Сообщение от voraa
|
В какой момент вы смотрите?
Когда вы выполняете
14 console.log(window);
там еще не будет responseCustom потому, что onreadystatechange еще не исполнился и присвоения не произошло
|
Аа, вот оно что. Получается надо settimeout ставить. либо делать await?
|
|
07.12.2020, 16:29
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,744
|
|
Так бы этот метод переписать
#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
}
})
}
Последний раз редактировалось voraa, 07.12.2020 в 16:54.
|
|
07.12.2020, 19:12
|
Аспирант
|
|
Регистрация: 05.04.2018
Сообщений: 77
|
|
Спасибо!
|
|
|
|