如何等待一个函数的内部过程执行完再返回?
How to wait for the internal process of a function to execute completely before returning?
我正在尝试使用 axios 和 cheerio 获取网页,但我无法检索所有数据,因为函数是甚至在内部过程完全完成之前返回。我正在使用 ReactJS,当我单击页面中的按钮时,将调用此函数:
analyse = async(e) => {
this.a = await axios.get('xxx');
this.s = await axios.get('yyy');
this.f = await axios.get('zzz');
let aReturn = this.fetchA(this.a.data);
let sReturn = this.fetchS(this.s.data);
let fReturn = this.fetchF(this.f.data);
if(await fReturn === true && await aReturn === true && await sReturn === true){
anotherFunction();
}
}
在上面的代码中,axios 工作正常,函数 fetchA()
和 fetchS()
是简单的函数,没有任何进一步的内部函数调用:
fetchA(html){
const $ = cheerio.load(html);
//some process
return true;
}
fetchS(html){
const $ = cheerio.load(html);
//some process
return true;
}
没有完全执行就返回的函数是fetchF()
:
fetchF(html){
const $ = cheerio.load(html);
$('div._someClassName').children().each((i,elem) => {
let link = $(elem).find('a').first().attr('href');
axios.get(link)
.then(response => {
this.deepF(response.data);
})
.catch(err => {
console.log("Error : ",err);
})
};
return true;
}
在上面的函数中,每个 child 中都有一个唯一的 link,我需要再次 axios.get()
并调用另一个函数 deepF()
来获取那个数据页。
内部函数 deepF 又是一个小函数:
deepF(html){
const $ = cheerio.load(html);
//some process
return true;
}
在这整个代码中,fetchF()
返回 true 而没有在内部完全执行所有 deepF()
函数。
注:所有deepF()
函数在fetchF()
returns true
之后缓慢执行
如何在 fetchF()
返回 true 之前等待 fetchF()
执行所有内部 deepF()
?
将 fetchF()
的实现更改为正确地 return 链接到所有 ajax 调用的承诺。将 ajax promises 累积到一个数组中,然后使用 Promise.all()
知道它们何时全部完成。然后,您可以 await
该函数的结果。
由此变化:
fetchF(html){
const $ = cheerio.load(html);
$('div._someClassName').children().each((i,elem) => {
let link = $(elem).find('a').first().attr('href');
axios.get(link)
.then(response => {
this.deepF(response.data);
})
.catch(err => {
console.log("Error : ",err);
})
};
return true;
}
对此:
fetchF(html){
const $ = cheerio.load(html);
const promises = [];
$('div._someClassName').children().each((i,elem) => {
let link = $(elem).find('a').first().attr('href');
promises.push(axios.get(link).then(response => {
return this.deepF(response.data);
}).catch(err => {
console.log("Error : ",err);
throw err;
}));
});
return Promise.all(promises).then(() => true).catch(() => false);
}
这使得 fetchF()
成为一个函数,return 是一个承诺,只有当它内部的所有 axios.get()
调用都完成并以 true
值解析时才解析。如果有任何错误,它会捕获这些错误并用 false
值解决(这似乎是您想要的逻辑,尽管不只是让被拒绝的承诺传播并在更高级别捕获它有点不寻常表示错误)。
然后,您可以使用:
let fReturn = await this.fetchF(this.f.data);
然后 fReturn
将是 true
或 false
。
如果您的任何其他函数中有异步操作,它们还需要 return 一个直接链接到您的异步操作的承诺。
我正在尝试使用 axios 和 cheerio 获取网页,但我无法检索所有数据,因为函数是甚至在内部过程完全完成之前返回。我正在使用 ReactJS,当我单击页面中的按钮时,将调用此函数:
analyse = async(e) => {
this.a = await axios.get('xxx');
this.s = await axios.get('yyy');
this.f = await axios.get('zzz');
let aReturn = this.fetchA(this.a.data);
let sReturn = this.fetchS(this.s.data);
let fReturn = this.fetchF(this.f.data);
if(await fReturn === true && await aReturn === true && await sReturn === true){
anotherFunction();
}
}
在上面的代码中,axios 工作正常,函数 fetchA()
和 fetchS()
是简单的函数,没有任何进一步的内部函数调用:
fetchA(html){
const $ = cheerio.load(html);
//some process
return true;
}
fetchS(html){
const $ = cheerio.load(html);
//some process
return true;
}
没有完全执行就返回的函数是fetchF()
:
fetchF(html){
const $ = cheerio.load(html);
$('div._someClassName').children().each((i,elem) => {
let link = $(elem).find('a').first().attr('href');
axios.get(link)
.then(response => {
this.deepF(response.data);
})
.catch(err => {
console.log("Error : ",err);
})
};
return true;
}
在上面的函数中,每个 child 中都有一个唯一的 link,我需要再次 axios.get()
并调用另一个函数 deepF()
来获取那个数据页。
内部函数 deepF 又是一个小函数:
deepF(html){
const $ = cheerio.load(html);
//some process
return true;
}
在这整个代码中,fetchF()
返回 true 而没有在内部完全执行所有 deepF()
函数。
注:所有deepF()
函数在fetchF()
returns true
如何在 fetchF()
返回 true 之前等待 fetchF()
执行所有内部 deepF()
?
将 fetchF()
的实现更改为正确地 return 链接到所有 ajax 调用的承诺。将 ajax promises 累积到一个数组中,然后使用 Promise.all()
知道它们何时全部完成。然后,您可以 await
该函数的结果。
由此变化:
fetchF(html){
const $ = cheerio.load(html);
$('div._someClassName').children().each((i,elem) => {
let link = $(elem).find('a').first().attr('href');
axios.get(link)
.then(response => {
this.deepF(response.data);
})
.catch(err => {
console.log("Error : ",err);
})
};
return true;
}
对此:
fetchF(html){
const $ = cheerio.load(html);
const promises = [];
$('div._someClassName').children().each((i,elem) => {
let link = $(elem).find('a').first().attr('href');
promises.push(axios.get(link).then(response => {
return this.deepF(response.data);
}).catch(err => {
console.log("Error : ",err);
throw err;
}));
});
return Promise.all(promises).then(() => true).catch(() => false);
}
这使得 fetchF()
成为一个函数,return 是一个承诺,只有当它内部的所有 axios.get()
调用都完成并以 true
值解析时才解析。如果有任何错误,它会捕获这些错误并用 false
值解决(这似乎是您想要的逻辑,尽管不只是让被拒绝的承诺传播并在更高级别捕获它有点不寻常表示错误)。
然后,您可以使用:
let fReturn = await this.fetchF(this.f.data);
然后 fReturn
将是 true
或 false
。
如果您的任何其他函数中有异步操作,它们还需要 return 一个直接链接到您的异步操作的承诺。