我试图使用superagent来获取网页中的链接,并从该链接中的另一个表中获取值。
到目前为止,我已经在console.log中成功了,但是在尝试使用异步调用返回对象时遇到了问题。
await request
函数中的第一个getData
工作正常,getOrder
内另一个也在cheerio .each
内的工作不能按预期工作。
在这里提到cheerio因为我不确定导致问题的原因
这是我迄今为止所做的事情
const request = require('superagent');
const cheerio = require('cheerio')
server.get('/crawler', (req, res) => {
const data = await getData(url)
console.log('data loaded ')
res.send(data)
})
const getData = async (url) => {
console.log('before root')
const result = await request.get(url).set(header)
console.log('after root')
const $ = cheerio.load(result.text);
let p = Promise.resolve();
$('table').first().find('tr').each(async (i, row) => {
p = p.then(async () => {
console.log('order no', row.orderNo)
let viewOrder = await getOrder(row.url)
console.log('after getOrder')
// .... build data here
})
})
p.then(() => {
// ....
return data
})
}
const getOrder = async (url) => {
console.log('before call')
const result = await request.get(url).set(header)
// the response return before this line in 1st round of loop
console.log('called', url)
const $ = cheerio.load(result.text);
let p = Promise.resolve();
$('table').first().find('tr').each(async (i, row) => {
p = p.then(async () => {
// .... build data here
})
})
p.then(() => {
return data
})
}
输出
before root
after root
order no 1
before call
data loaded
GET /crawler <<<<<<< res.send here
called ...
after getOrder
order no 2
before call
called ...
after getOrder
before call
order no 3
called ...
after getOrder
它应该是什么
程序应该等待所有请求被调用然后返回响应
答案 0 :(得分:0)
尝试这种模式:
function doSomething() {
return () =>
fetch('/api/something').then(response => response.json())
}
function doSomethingElse() {
return () =>
fetch('/api/something').then(response => response.json())
}
function doEverything() {
return () => Promise.all([
doSomething(),
doSomethingElse()
]);
}
答案 1 :(得分:0)
经过一些研究后,我发现我需要将该函数包装在Promise
和resovle
中,以使其与await
一起使用
const getData = (url) => {
return new Promise(async (resolve, reject) => {
console.log('before root')
const result = await request.get(url).set(header)
console.log('after root')
const $ = cheerio.load(result.text);
let p = Promise.resolve();
$(tableSelector).first().find('tr').each(async (i, row) => {
p = p.then(async () => {
console.log('order no', row.orderNo)
let viewOrder = await getOrder(row.url)
console.log('after getOrder')
// .... build data here
})
})
p.then(() => {
// ....
resolve(data)
})
})
}
const getOrder = async (url) => {
return new Promise(async (resolve, reject) => {
console.log('before call')
const result = await request.get(url).set(header)
console.log('called', url)
const $ = cheerio.load(result.text);
let p = Promise.resolve();
$(tableSelector).first().find('tr').each(async (i, row) => {
p = p.then(async () => {
// .... build data here
})
})
p.then(() => {
resolve(data)
})
})
}