Дождитесь ответа от node.js запрос с использованием await

#node.js

#node.js

Вопрос:

Да, я видел много других вопросов и ответов.Я знаю, что мне нужно использовать ответ обратного вызова. Тем не менее, я все еще не понимаю, как выполнить этот конкретный пример. В большинстве примеров используется ответ обратного вызова, который регистрирует что-либо, или сообщение содержит сотни разных ответов.

Как мне вернуть ответ на запрос из getPageData?

 var url = "myurl";
var name = await getPageData(url);
// wait until I get name and then do stuff with name

function getPageData(url)
{
    const https = require('https');
    https.get(url, (resp) => {
    
        let data = '';

        resp.on('data', (chunk) => {
            data  = chunk;
        });

        resp.on('end', () => {
            var name = JSON.parse(data);
            // what do I do here to get name out?
        });

    }).on("error", (err) => {
       console.log("Error: "   err.message);
    });
}
  

Ответ №1:

await может использоваться только в async функциях. Однако вы можете вернуть обещание getPageData и «ожидать», используя chained then :

Используйте объект Promise:

 const https = require('https');

var url = "myurl";
var name; 
getPageData(url)
 .then(data => { name = data; /*This is the scope in which you would use name*/ })
 .catch(err => { console.log('Error occured', err); });

async function getPageData(url) {
  return new Promise((resolve, reject) => {
    https
      .get(url, resp => {
        let data = '';

        resp.on('data', chunk => {
          data  = chunk;
        });

        resp.on('end', () => {
          const name = JSON.parse(data);
          // what do I do here to get name out?
          resolve(name);
        });
      })
      .on('error', err => {
        console.log(`Error: ${err.message}`);
        reject(err);
      });
  });
}

  

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

1. Это выдает ошибку «ожидание допустимо только в асинхронной функции»

2. Ах да. Верно, вы можете использовать только await в асинхронных функциях. Вместо этого вам придется использовать then . Я обновлю ответ.

3. async Ключевое слово return new Promise является избыточным. Просто используйте return new Promise .

4. @Take-Some-Bytes конечно, не помешает быть явным, хотя

Ответ №2:

Решение более высокого уровня здесь заключается в использовании модуля для выполнения http-запросов, которые уже поддерживают promises. Вы можете увидеть список многих из них здесь . Мой любимый из этого списка — got(), и вы можете использовать его для решения своей проблемы следующим образом:

 function getPageData(url) {
    return got(url);
}

// can only use await inside a function declared as async
async function someFunction() {
    try {
        let name = await getPageData(url);
        console.log(name);
    } catch(e) {
        console.log(e);
    }
}
  

got() Библиотека делает за вас целую кучу вещей.

  1. Он полностью основан на обещаниях, поэтому вы можете напрямую использовать await обещание, которое он возвращает.
  2. Он собирает весь ответ для вас (вам не нужно писать свой собственный код для этого).
  3. Если ответ представляет собой JSON, он автоматически анализирует его для вас и преобразует в проанализированный объект Javascript.
  4. Он автоматически определяет URL-адрес http или https и использует правильный низкоуровневый модуль.
  5. И у него есть десятки других полезных функций (не необходимых в этом примере).

Или, если вам нужно решение более низкого уровня, в котором вы создаете свою собственную функцию promisified для выполнения запроса https, вы можете сделать это:

 const https = require('https');

// can only use await inside a function declared as async
async function someFunction() {
    const url = "myurl";
    try {
        let name = await getPageData(url);
        console.log(name);
    } catch(e) {
        console.log(e);
    }
}



function getPageData(url) {
    return new Promise((resolve, reject) => {
        https.get(url, (resp) => {

            let data = '';

            resp.on('data', (chunk) => {
                data  = chunk;
            });

            resp.on('end', () => {
                try {
                    const name = JSON.parse(data);
                    resolve(name);
                } catch(e) {
                    // JSON parsing error
                    reject(e);
                }
            });

        }).on("error", (err) => {
            console.log("Error: "   err.message);
            reject(err);
        });
    }).on('error', (err) => {
        console.log("Error: "   err.message);
        reject(err);
    });
}