Возврат объекта из обратного вызова с использованием async / await

Я не могу решить этот вопрос с ответами на этот вопрос, потому что есть различия в коде.

Я хочу вернуть объект из обратного вызова. Когда я запускаю приведенный ниже код, журнал body выглядит так, как ожидалось. Похоже, это правильный объект JSON, содержащий нужный мне ответ от сервера: имя, адрес электронной почты, веб-сайт и т. Д.

Но объект result содержит информацию о самом запросе, а не объекте ответа.

Как мне вернуть объект body чтобы я мог получить к нему доступ из переменной result ?

const request = require('request'); // npm i request -s

module.exports = async config => {
  ...

  const result = await request.get( url, options,
    ( error, response, body, ) => {
      console.log( 'body', body, ); // I want the other log to look like this log.
      return body;
    }
  );

  console.log( 'result', result, ); // I want this log to look like the above log.
  // In other words, I want the below line to be the name, email, website JSON object
  // contained in the body
  return result;
}

Это то , что я хочу от result .

console.log ('body', body,);
body {
  "name": "foo",
  "email": "foo@example.com",
  "website": "www.example.com",
  ...
}

Это то, что я на самом деле получаю из result .

console.log ('result', result,);
result Request {
  _events: [Object: null prototype] {
    error: [Function: bound ],
    complete: [Function: bound ],
    pipe: [Function]
  },
  _eventsCount: 3,
  _maxListeners: undefined,
  uri: Url {
    protocol: 'https:',
    slashes: true,
    auth: null,
    host: 'api.example.com',
    port: 443,
    hostname: 'api.example.com',
    hash: null,
  },
  callback: [Function],
  method: 'GET',
  readable: true,
  writable: true,
  explicitMethod: true,
  _qs: Querystring {
    request: [Circular],
    lib: { formats: [Object], parse: [Function], stringify: [Function] },
    useQuerystring: undefined,
    parseOptions: {},
    stringifyOptions: {}
  },
  _auth: Auth {
    request: [Circular],

Всего 2 ответа


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

const result = await new Promise((resolve) => {
  request.get(url, options, (error, response, body) => {
      console.log( 'body', body );
      resolve(body);
    });
});

Редактировать:

или вы можете установить https://github.com/request/request-promise


request.get() НЕ возвращает обещание, поэтому await на нем ничего полезного не делает. Если бы у меня был никель за каждый раз, когда я отвечал на этот вопрос, у меня было бы много никелей. await не имеет магии. Все, что он делает, это ждать обещания. Это ничего не даст, если вы не дадите обещание.

Возможно, вы не знаете, но модуль request и его производные находятся в режиме обслуживания (без новых функций, только исправления ошибок). Вы можете либо воспользоваться модулем request-promise а затем избавиться от обратного вызова, либо переключиться на более новый активно развивающийся модуль, такой как got модуль. Это было бы моей рекомендацией:

const got = require('got');

module.exports = async config => {
  ...

  const result = await got(url, options);

  console.log( 'result', result ); // I want this log to look like the above log.
  // In other words, I want the below line to be the name, email, website JSON object
  // contained in the body
  return result;
}

И, я надеюсь, вы понимаете, что ВСЕ async функции возвращают обещание, поэтому вызывающая сторона этой функции должна будет использовать await или .then() в возвращенном обещании, чтобы получить результат из обещания.


Если вы хотите остаться с библиотекой request , вы можете использовать request-promise чтобы получить уже обещанную версию библиотеки:

const rp = require('request-promise');

module.exports = async config => {
  ...

  const result = await rp(url, options);

  console.log( 'result', result ); // I want this log to look like the above log.
  // In other words, I want the below line to be the name, email, website JSON object
  // contained in the body
  return result;
}

Есть идеи?

10000