javascript - 等到所有 http GET 请求完成后再登录到 JS 中的控制台
问题描述
Javascript/Node 菜鸟在这里。在理解 JS 的整个异步方面时遇到了一些麻烦。我正在构建一个小型应用程序,其目的是调用外部 API,然后存储结果以用于日志记录。
无论如何,我有一个看起来像这样的 GET 请求
request(callsOptions)
.then(function (res) {
//Request success... do some logic with the response object
var content = JSON.stringify(res)
//save result to a file with the name as m-d-yyyy.json
fs.writeFile(`callLogs/${month}-${day}-${year}.json`, content, 'utf8', function (err) {
if (err) {
return console.log(err);
}
})
//get session_ids and call destinations and store in the 2 diff arrays
var calls = res.calls
for(let x = 0; x < calls.length; x++){
session_ids[x] = calls[x].session_id
dests[x] = calls[x].dest
}
//make an individual req for each call in the array
for(let x = 0; x < calls.length; x++){
getCallLog(session_ids[x], dests[x])
}
}).catch(function (err) {
//Request failure...
console.log('Whoops... something went wrong with the calls request!')
})
然后调用 getCallLog 方法,该方法获取从前一个请求中提取的信息并进行更多调用
function getCallLog(id, dest){
request(constructURL(id))
.then(function (res) {
//Request success... do some logic with the response object
console.log('Request success!')
var content = JSON.stringify(res)
fs.writeFile(`${dest}/${id}.json`, content, 'utf8', function (err) {
if (err) {
return console.log(err);
}
})
//return res
}).catch(function (err) {
//Request failure...
console.log('Whoops... something went wrong with the call request!')
})
}
所以,我想等到所有 GET 请求完成之后再做一些逻辑。目前,该逻辑将简单地类似于
console.log('DONE')
问题是由于 JS 的异步方面,我尝试过的所有操作都会在完成之前显示 DONE。所以,我只是等待一段时间以确保所有请求都已完成。
我尝试过的事情:
- 当循环完成时,将 if 语句放入 for 循环中
- 在 getCallLog().then() 函数中使用计数器
编辑:像这样?
const { promisify } = require("util")
...
request(callsOptions)
.then(function (res) {
//Request success... do some logic with the response object
var content = JSON.stringify(res)
//save result to a file with the name as m-d-yyyy.json under the callLogs folder
fs.writeFile(`callLogs/${month}-${day}-${year}.json`, content, 'utf8', function (err) {
if (err) {
return console.log(err);
}
})
//get session_ids and call destinations and store in the 2 diff arrays
var calls = res.calls
for (let x = 0; x < calls.length; x++) {
session_ids[x] = calls[x].session_id
dests[x] = calls[x].dest
}
//make an individual req for each call in the array
const promises = [];
for (let x = 0; x < calls.length; x++) {
promises.push(getCallLog(session_ids[x], dests[x]))
}
return Promise.all(promises)
}).then(function(){
console.log("All done!")
}).catch(function (err) {
//Request failure...
fs.writeFile(`errorlog/${month}-${day}-${year}.json`, content, 'utf8', function (err) {
if (err) {
return console.log(err);
}
})
})
function getCallLog(id, dest){
request(constructURL(id))
.then(function (res) {
//Request success... do some logic with the response object
console.log('Request success!')
var content = JSON.stringify(res)
return promisify(fs.writeFile)(`${dest}/${id}.json`, content, 'utf8');
}).catch(function (err) {
//Request failure...
fs.writeFile(`errorlog/${month}-${day}-${year}-${id}.json`, err, 'utf8', function (err) {
if (err) {
return console.log(err);
}
})
})
}
解决方案
只需从内部函数返回一个承诺并承诺文件写入:
const { promisify } = require("util");
function getCallLog(id, dest){
return request(constructURL(id)) // <-- return the promise
.then(function (res) {
//Request success... do some logic with the response object
console.log('Request success!')
var content = JSON.stringify(res)
return promisify(fs.writeFile)(`${dest}/${id}.json`, content, 'utf8');
}).catch(function (err) { // also catches writing errors
console.log('Whoops... something went wrong with the call request!')
});
}
现在您可以在.your 循环中收集所有承诺:
const promises = [];
for(let x = 0; x < calls.length; x++){
promises.push(getCallLog(session_ids[x], dests[x]));
}
然后将这些承诺返回到链中:
return Promise.all(promises);
因此,现在您可以将 a 添加.then(...)
到随后将执行的链中:
.then(() => console.log("All done!"));