Я - разработчик .Net, новичок в мире javascript / node и испытываю некоторые затруднения с выполнением запроса на получение HTML-кода с веб-страницы с помощью запроса-обещания. Я пробовал варианты кода ниже.
import cheerio = require('cheerio');
import request = require('request-promise');
export class Address {
public html;
public $: CheerioStatic;
constructor() {
this.html = this.makeRequest();
}
private async makeRequest() {
const options = {
uri: 'https://www.google.com/',
transform(body) {
return cheerio.load(body);
}
};
return await request(options);
}
}
Проблема в том, что когда я устанавливаю переменную this.html, вызывая метод this.makeRequest (), я получаю Promise { pending }
возвращаемое значение. Я не уверен, почему это так. Из того, что я исследовал, не ждет, дождаться обещания, которое будет выполнено? Я тоже пробовал с синтаксисом .then
, но получаю еще более странный результат:
Promise {_bitField: 0, _fulfillmentHandler0: undefined, _rejectionHandler0: undefined, _promise0: undefined, _receiver0: undefined, …}
. Версия makeRequest (), которая возвращает это странное обещание, приведена ниже.
private makeRequest() {
const options = {
uri: 'https://www.google.com/',
transform(body) {
return cheerio.load(body);
}
};
return request(options)
.then(function($: CheerioStatic) {
return $;
})
.catch(function(err) {
//
});
}
Я хотел бы придерживаться синтаксиса async / await, но любая помощь в объяснении, почему мой код не работает и что я мог сделать, чтобы исправить это, была бы признательна!
Обновление
В соответствии с предложением @basarat, я сделал другой асинхронный метод, используя ключевое слово await для установки свойства. Мой код ниже. Я также попытался с и без ключевых слов async / await в методе getRequest. В любом случае, моя собственность теперь возвращается как undefined
. Не уверен, что это шаг в правильном направлении или нет.
import cheerio = require('cheerio');
import request = require('request-promise');
export class Address {
public html;
public $: CheerioStatic;
constructor() {
this.getHtml();
// this.parseHtml();
}
private async makeRequest() {
const options = {
uri: 'https://www.google.com/',
transform(body) {
return cheerio.load(body);
}
};
return await request(options);
}
private async getHtml() {
this.html = await this.makeRequest();
}
}
Обновление 2
Итак, не зная, что делать, я решил снова попробовать маршрут обещаний с модулем запроса вместо запроса-обещания. В моей функции makeRequest()
я возвращаю новое обещание, которое оборачивает мой запрос, а затем вызываю .then()
для него в методе getHtml()
. Следует также отметить, что я тестирую этот код с помощью модульных тестов mocha. Не уверен, что это как-то связано с этим. Я тоже пытался сделать тестовый асинхронный тест и использовать await, но без сигары. Ниже приведены мой класс и тест.
import request = require('request');
export class Address {
public html;
constructor() {
this.html = this.getHtml();
}
public getHtml() {
this.makeRequest().then((body) => {
console.log(body);
return body;
});
}
private makeRequest() {
return new Promise(function(resolve, reject) {
request('https://www.google.com/', function(error, response, body) {
if (error) {
reject(error);
}
resolve(body);
});
});
}
}
Последнее замечание. Я вставил console.log(body);
в метод getHtml (), чтобы увидеть, вызывается ли он. Когда я запускаю модульный тест и ставлю точку останова где-нибудь в тесте, она никогда не вызывается, даже если я создал экземпляр своего класса. Однако, когда я продолжаю выполнение и заканчиваю тест, он печатает весь HTML! Поэтому мне кажется, что самый последний код в основном хорош, но, возможно, происходит какая-то проблема с синхронизацией. Поскольку HTML-код все еще распечатывается, вызов по крайней мере выполняется, но он не поступает в мою собственность. Ниже тест, который я выполняю.
describe('Address', () => {
// const address = new Address();
it('is not empty', () => {
const address = new Address();
const ad = address.html;
// console.log(ad);
});
});
Кроме того, в тесте я попытался сделать асинхронную инструкцию it
и добавить await
в address.html (также пытался дождаться создания экземпляра), и снова не было сигары.