Вытащить return из callback функции

Тема в разделе "JavaScript", создана пользователем yaski, 7 окт 2018.

  1. yaski

    yaski

    Moderator
    Регистр.:
    21 фев 2010
    Сообщения:
    554
    Симпатии:
    351
    Есть функция js
    HTML:
    function getData(){
            var options = {
                 fromBlock: 0,
                 toBlock: 'latest',
                 address: address
                };
            var filter = web3.eth.filter(options);
            filter.get(function res(error, eventResult){
                if (!error)
                    data = JSON.stringify(eventResult, null, 2);
                console.log(data);
              return data;
            });
        };
    В консоли выводятся полученные значения data. Подскажите как получить значения data из callback функции res в основную функцию.
    з.ы. C промисами не дружу(
     
  2. Viodele

    Viodele Механик

    Administrator
    Регистр.:
    17 дек 2011
    Сообщения:
    131
    Симпатии:
    547
    var blah = filter.get(...
     
    yaski нравится это.
  3. yaski

    yaski

    Moderator
    Регистр.:
    21 фев 2010
    Сообщения:
    554
    Симпатии:
    351
    Результат все равно не возвращается, возвращается текст запроса
     
  4. Viodele

    Viodele Механик

    Administrator
    Регистр.:
    17 дек 2011
    Сообщения:
    131
    Симпатии:
    547
    Теперь дошло. Я не особо знаю, что делает ф-ция web3.eth.filter(...), но самый банальный вариант - это объявить глобальную переменную а-ля lastStoredData и внутри ф-ции res просто сохранять data в lastStoredData. Соответственно, после каждого выполнения filter.get(...) в переменно lastStoredData будет последнее использованное значение переменной data.
     
  5. yaski

    yaski

    Moderator
    Регистр.:
    21 фев 2010
    Сообщения:
    554
    Симпатии:
    351
    undefined выдает((
    Походу без промисов никак
    Функция в ajax запросе вызывается, а там асинхрон
    если вешаю ее на клик по кнопке, все нормально отрабатывается и выдает результат
     
    Последнее редактирование: 7 окт 2018
  6. Viodele

    Viodele Механик

    Administrator
    Регистр.:
    17 дек 2011
    Сообщения:
    131
    Симпатии:
    547
    Если lastStoredData объявлена правильно, в области window, то undefined ты можешь получать только в том случае, если пытаешься взять из нее данные раньше, чем они присвоены. Такое, в первую очередь, наблюдается в тех случаях, когда колбэки пытаются по сети тянуть какие-то данные, на что уходит время. В таких случаях есть 2 вариант: 1) синхронное выполнение; 2) проверять результат спустя некоторое время. Для реализации второго варианта можно попробовать использовать setTimer/setInterval. Я не уверен, что промисы решат данный вопрос.
     
  7. BaNru

    BaNru

    Регистр.:
    20 ноя 2008
    Сообщения:
    155
    Симпатии:
    69
    Или перейти на промисы. Я так понимаю именно это ТС и надо. Либо сделать callback внутри данной функции.

    На промисах
    https://jsfiddle.net/BaNru/jd73uxpr/
    На callback
    https://jsfiddle.net/BaNru/jd73uxpr/1/

    На промисах функция остаётся переиспользуемой (в других функциях, отдельно можно вызвать). На callback соответственно нет.

    PS Извиняюсь, конечно выше речь не про callback в полном смысле этого термина, а для обозначения варианта решения.
     
    Последнее редактирование: 12 окт 2018
    yaski нравится это.
  8. yaski

    yaski

    Moderator
    Регистр.:
    21 фев 2010
    Сообщения:
    554
    Симпатии:
    351

    А как результат загнать в аякс запрос в data вместо eRes?
    В консоли содержимое eRes отображается
    HTML:
    
      function getData(){
         return new Promise(function(resolve, reject) {
            var options = {
              fromBlock: 0,
              toBlock: 'latest',
              address: address
             };
           var filter = web3.eth.filter(options);
           data2 = filter.get(function res(error, eventResult){
             if (!error)
               eResult = JSON.stringify(eventResult, null, 2);
           });
         //return(eResult);
         setTimeout(function(){
         resolve(eResult);
         },2000);
       })
      };
    
      function update() {
          var eRes;
          $.ajax({
              url: "update.php",
              datatype: "json",
              type: "POST",
              data: eRes,
                       
              beforeSend: function(){
                  getData().then(function(eRes){
                      console.log(eRes);
                  })
              });
      }
      }
     
  9. BaNru

    BaNru

    Регистр.:
    20 ноя 2008
    Сообщения:
    155
    Симпатии:
    69
    Не совсем понимаю что надо.

    Код:
    function update() {
       getData().then(function(answer){
          var eRes;
          $.ajax({
              url: "update.php",
              datatype: "json",
              type: "POST",
              data: answer,
                
              beforeSend: function(res){
                      console.log(res);
              }
            })
        })
    }
    Вместо beforeSend обычно используют что-то типа done или success
    Если используется jQ, то стоит почитать справку, что за что отвечает
    http://api.jquery.com/jquery.ajax/
     
    yaski нравится это.
  10. BaNru

    BaNru

    Регистр.:
    20 ноя 2008
    Сообщения:
    155
    Симпатии:
    69
    Я надеюсь в примере понятно показал, что setTimeout использован чтобы эмулировать ассинхронную функцию.
    В твоём случае надо писать как я написал в заккоментированом коде, специально его вставил:
    вместо return eResult - вставляется resolve(eResult), это своего рода аналог в промисах.
    Либо reject, если это ошибка. По сути тоже аналог return, но позваляет промисам понять, что произошла ошибка.
    То есть представь, что ты возвращаешь объект
    Код:
    return : {
      done : "всё хорошо прекрасная Маркиза",
      еrror : 'ошибок нет'
    }
    И чтобы потом не проверять if/else return.done/return.еrror, грубо говоря и используется resolve() и reject().
    И потом jquery подобный лапшевидный код проверяет, он же аналогичен try/catch
    Код:
    FUNCTION()
      .then(function(){}) // Тут выполняем функцию если нет ошибок
      .catch(function(){}) // Тут выполняем функцию если есть ошибка
    
     
    yaski нравится это.