Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 07.12.2020, 15:31
Аспирант
Отправить личное сообщение для SolomonRei Посмотреть профиль Найти все сообщения от SolomonRei
 
Регистрация: 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);


Подскажите пожалуйста в чем проблема может быть
Изображения:
Тип файла: jpg download.jpg (8.9 Кб, 2 просмотров)
Тип файла: jpg download (1).jpg (11.2 Кб, 1 просмотров)

Последний раз редактировалось SolomonRei, 07.12.2020 в 15:34.
Ответить с цитированием
  #2 (permalink)  
Старый 07.12.2020, 15:57
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,744

Мало информации.

Что возвращает метод #checkFileExist? Он синхронный?

Сообщение от SolomonRei
я вызываю back функцию, которая дальше идет, и возвращает в ответ промис, который я хочу вернуть из функции.
А что вы возвращаете, когда #checkFileExist не срабатывает?
А что возвращаете, если if(back) ложно?
Ответить с цитированием
  #3 (permalink)  
Старый 07.12.2020, 16:02
Аспирант
Отправить личное сообщение для SolomonRei Посмотреть профиль Найти все сообщения от SolomonRei
 
Регистрация: 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);

                                }
                        });
Ответить с цитированием
  #4 (permalink)  
Старый 07.12.2020, 16:03
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,744

Сообщение от SolomonRei
Я вижу, в консоле, что св-во есть (смотри вложения)
console.log(window);
Но когда пытаюсь напрямую обратиться, то пишет undefined
console.log(window.responseCustom);
В какой момент вы смотрите?
Когда вы выполняете
14 console.log(window);
там еще не будет responseCustom потому, что onreadystatechange еще не исполнился и присвоения не произошло
Ответить с цитированием
  #5 (permalink)  
Старый 07.12.2020, 16:04
Аспирант
Отправить личное сообщение для SolomonRei Посмотреть профиль Найти все сообщения от SolomonRei
 
Регистрация: 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);
            });
        }
    }
Ответить с цитированием
  #6 (permalink)  
Старый 07.12.2020, 16:05
Аспирант
Отправить личное сообщение для SolomonRei Посмотреть профиль Найти все сообщения от SolomonRei
 
Регистрация: 05.04.2018
Сообщений: 77

Сообщение от voraa Посмотреть сообщение
В какой момент вы смотрите?
Когда вы выполняете
14 console.log(window);
там еще не будет responseCustom потому, что onreadystatechange еще не исполнился и присвоения не произошло
Аа, вот оно что. Получается надо settimeout ставить. либо делать await?
Ответить с цитированием
  #7 (permalink)  
Старый 07.12.2020, 16:29
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 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.
Ответить с цитированием
  #8 (permalink)  
Старый 07.12.2020, 19:12
Аспирант
Отправить личное сообщение для SolomonRei Посмотреть профиль Найти все сообщения от SolomonRei
 
Регистрация: 05.04.2018
Сообщений: 77

Спасибо!
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как передать данные из одинаковых форм php скрипту через AJAX? griga999 AJAX и COMET 22 10.10.2016 06:09
как с помощью javascript взять данные из одного файла html и закинуть в другой? rusik Общие вопросы Javascript 10 08.08.2016 12:11
Как вставить данные в highcharts? user71 Общие вопросы Javascript 40 08.08.2016 03:31
Как из php файла передать данные в переменную javascript angelzzz Общие вопросы Javascript 36 01.07.2016 15:54
Как подгрузить данные с чужого домена, XSS-proof? Actine AJAX и COMET 6 03.09.2011 22:08