Дождитесь ответа от запроса, прежде чем возвращаться

#javascript #electron

Вопрос:

Я пытаюсь создать функцию с запросом GET, которая возвращает часть данных из запроса GET. Однако он продолжает возвращаться до получения данных, поэтому я продолжаю получать «неопределенное». Как я могу настроить это так, чтобы оно действительно ожидало установки данных перед возвращением?

 let getInfo = async () => {
  const request = net.request({
    url: URL
  })
  
  return new Promise((resolve, reject) => { // Promise being here DOES work
    request.on('response', (response) => {
      response.on('data', (chunk) => {

        //return new Promise((resolve, reject) => { //Promise being here does NOT work
          let body = JSON.parse(chunk)
          let info = body.data
          if (info){
            resolve(info);
          }
          reject();
        //})
      });

    });

    request.write('')
    request.end()
  }).then(data => {
    console.log("From then: " data)
    return data
  })
}

getInfo().then(data => {
  console.log("From outside: " data)
})
 

Изменить: Это обновленная версия, которая все еще не работает. Я пытаюсь использовать собственный электронный метод, и я не понимаю, почему это не работает. Часть «С тех пор:» отображает информацию правильно. Но при запуске «извне:» он печатает неопределенное. Имеет ли проблема какое-либо отношение к response.on вложенности внутри request.on ?

Решение: Как показал @NidhinDavid в своем ответе, проблема заключалась в том, что обещание было внутри 'response' слушателя. Перемещение 'GET' запроса от начала до конца внутри Обещания привело к тому, что он выдал правильный вывод. Я обновил свой код, чтобы отразить это для будущих пользователей.

Комментарии:

1. Это основы, и некоторые гуглы дадут вам ответ. Что касается стартера, попробуйте использовать console.log(await getInfo())

2. Можете ли вы дать ссылку, откуда вы импортируете сеть ?

3. @NidhinDavid Я несколько раз гуглил его, просматривал десятки страниц и пробовал много разных вещей. То, что вы предложили, было первым, что я попробовал, и это не сработало.

4. @Bazoogle Я добавил ответ, чтобы помочь вам выбраться из фюстрации. Надеюсь, это поможет!

5. Не обновляйте свой вопрос, чтобы больше не возникало проблем, для этого и предназначен раздел ответов. Теперь этот вопрос не имеет значения.

Ответ №1:

 let getInfo = () => {
  let info;

  const request = net.request({
    url: URL
  })

  return new Promise((resolve, reject) => {
    request.on('response', (response) => {
      response.on('data', (chunk) => {
        request.write('')
        request.end()
        let body = JSON.parse(chunk)
        info = body.data
        if (info) {
          resolve(info)
        } else {
          reject('Something went wrong');
        }
      });
    });
  })
}

getInfo()
  .then(data => {
    // this will be your info object
    console.log(data)
  })
  .catch(err => {
    // this will log 'Something went wrong' in case of any error
    console.log(err)
  }) 

Вам нужно вернуться в свой on обработчик событий типа. Подробнее об асинхронном коде и синхронном коде читайте здесь

Комментарии:

1. Я тоже пытался это сделать. и на нем все еще было напечатано «неопределенно»

2. Также проверьте, является ли data действительным ключ на body объекте

3. Кроме того, можете ли вы поделиться большей частью своего кода, чтобы я мог протестировать его локально, есть вероятность, что вам нужно вернуть обещание, и все будет хорошо работать для вас. Какая-либо конкретная причина для отказа от использования fetch ?

4. Если я console.log(info) изнутри прослушивателя ответа, и return info сразу после этого, он напечатает нормально, но журнал покажет undefined и тогда {correct info} . Я не могу поместить request.write и request.end внутри слушателя, потому что он никогда не сработает. У меня нет особых причин использовать этот метод, просто я создаю приложение electron и думал использовать собственный метод electron.

5. Хорошо, понял, дайте мне минуту, и я обновлю ответ, а затем попробуйте это

Ответ №2:

Я не смог найти net модуль, а тот, который входит в состав Nodejs, не имеет метода запроса. Поэтому, чтобы получить аналогичную концепцию эмуляторов событий и обещания, я использую http модуль и выполняю http-запрос для извлечения json и его анализа

 'use strict'

var https = require('https');


const getInfo = async () => {

  // create a new promise chain
  // remember it is a chain, if one return is omitted
  // then the chain is broken
  return new Promise((resolve, reject) => {

    var options = {
      host: 'support.oneskyapp.com',
      path: '/hc/en-us/article_attachments/202761727/example_2.json'
    };

    // start the request
    https.request(options, function (response) {
      var str = '';

      // data arrives in chunks
      // chunks needs to be stitched together before parsing
      response.on('data', function (chunk) {
        str  = chunk;
      });

      // response body obtained
      // resolve (aka return) the result
      // or parse it, or do whatever you want with it
      response.on('end', function () {
        resolve(str)

      });

      // errors are another event
      // listen for errors and reject when they are encountered
      response.on('error', function (err) {
        reject(err)
      })
    }).end()
  })
}

//*********************************************
// using async await
//*********************************************
// if this is the entry point into app
// then top-level async approach required
(async ()=>{
 try{
   let data = await getInfo()
   console.log("From ASYNC AWAIT ")
   console.log(JSON.stringify(JSON.parse(data)))
 }
 catch (err) {
   console.log("operation failed, error: ", err)
 }
})();

//************************************************
// using promise chains
//************************************************
getInfo()
.then((data)=>{
  console.log("FROM PROMISE CHAIN ")
  console.log(JSON.stringify(JSON.parse(data)))
})
.catch((err)=>{
  console.log("operation failed, error: ", err)
})
 

Комментарии:

1. Спасибо!!!! Проблема заключалась в том, что обещание было внутри 'response' слушателя. Я только что переместил весь GET запрос внутрь обещания, и теперь он работает так, как вы и ожидали! Я все еще использую собственный метод электронов, но то, что вы отправили свой запрос из обещания, заставило меня попробовать это, и это сработало. Ты спасаешь мне жизнь.

Ответ №3:

Тир, это может сработать для тебя,

 let info;
const getInfo = async (_url)=>{

const response = await fetch(_url);
const data = await response.json();
info = data; 
} ;

const url = "some url";

getInfo(url);
console.log(info);

 

Асинхронная функция всегда возвращает обещание, поэтому либо используйте это обещание, либо внутренне ожидайте данных и назначьте их какой-либо переменной.
Проверьте наличие действительных данных, необходимых в разделе информация, зарегистрировав их в консоли.

Комментарии:

1. У электрона изначально нет выборки. Я мог бы добавить его, но я пытался сохранить его только с помощью собственного метода для повышения эффективности electronjs.org/docs/api/client-request