递归使用 async/await 节点请求包
Using async/await recursively with node request package
我正在使用 response
节点库发出一个 http 请求,我正在尝试递归调用它(如果用户在某一天进行了提交,请检查前一天。如果没有,请计数获得连胜的所有日子)。
问题是那行
const githubResponse = await request(options);
吐出错误
Unexpected token o in JSON at position 1
await request(options)
似乎没有 return 我期待的 JSON GitHub API 响应,而是 githubResponse
似乎成为我无法使用的对象。我猜我使用 async/await
不当,但我不确定如何解决它。
async function checkUserCommitForDate(user, date) {
const options = {
url: `https://api.github.com/search/commits?q=author:${user}+author-date:${date}`,
headers: {
'User-Agent': 'request',
'Accept': 'application/vnd.github.cloak-preview'
}
};
const githubResponse = await request(options)
// I get an error on the next line
if (JSON.parse(githubResponse).total_count > 0) {
const previousDaysDate = moment(date).subtract(1, 'day').format('YYYY-MM-DD');
let streakCounter = await checkUserCommitForDate(user, previousDaysDate);
streakCounter++;
console.log('streakCounter', streakCounter);
return streakCounter;
} else {
return 0;
}
}
更新:这似乎不是一个承诺,所以我需要以不同的方式格式化它(作为回调)。当我尝试这个时:
async function checkUserCommitForDate(user, date) {
const options = {
url: `https://api.github.com/search/commits?q=author:${user}+author-date:${date}`,
headers: {
'User-Agent': 'request',
'Accept': 'application/vnd.github.cloak-preview'
}
};
request(options, async function (error, response, body) {
console.log('error:', error); // Print the error if one occurred
if (JSON.parse(body).total_count > 0) {
const previousDaysDate = moment(date).subtract(1, 'day').format('YYYY-MM-DD');
let streakCounter = await checkUserCommitForDate(user, previousDaysDate);
streakCounter++;
console.log('streakCounter', streakCounter);
return streakCounter;
} else {
return 0;
}
});
}
行
let streakCounter = await checkUserCommitForDate(user, previousDaysDate);
成为问题,因为 streakCounter
未定义,使日志 NaN
.
我使用这里的 promisify example 将其转换为这个并且成功了!
async function checkUserCommitForDate(user, date) {
const options = {
url: `https://api.github.com/search/commits?q=author:${user}+author-date:${date}`,
headers: {
'User-Agent': 'request',
'Accept': 'application/vnd.github.cloak-preview'
}
};
const githubResponse = await promisify(request)(options);
if (JSON.parse(githubResponse.body).total_count > 0) {
const previousDaysDate = moment(date).subtract(1, 'day').format('YYYY-MM-DD');
let streakCounter = await checkUserCommitForDate(user, previousDaysDate);
streakCounter++;
console.log('streakCounter', streakCounter);
return streakCounter;
} else {
return 0;
}
}
function promisify(fn) {
return function (...args) {
return new Promise((resolve, reject) => {
fn(...args, (err, result) => {
if (err) return reject(err);
resolve(result);
});
});
};
};
如评论中所述request uses callbacks instead of returning a promise and you dont really need to promisify it by yourself since there's already a pacakge for that called request-promise。
在您的代码中使用它应该直接与 async/await
开箱即用
如果升级到 Node 8 LTS,那么原生 util.promisfy 可以如下使用:
const { promisify } = require('util')
const request = promisify(require('request'))
async function checkUserCommitForDate(user, date) {
const options = {
url: `https://api.github.com/search/commits?q=author:${user}+author-date:${date}`,
headers: {
'User-Agent': 'request',
'Accept': 'application/vnd.github.cloak-preview',
'json':true
}
};
try{
const githubResponse = await request(options);
if (githubResponse.body.total_count > 0) {
const previousDaysDate = moment(date).subtract(1, 'day').format('YYYY-MM-DD');
let streakCounter = await checkUserCommitForDate(user, previousDaysDate);
streakCounter++;
console.log('streakCounter', streakCounter);
return streakCounter;
} else {
return 0;
}
}
catch(err){
console.error(err)
return 0;
}
}
在 选项 中使用 json:true 将减少另一个解析步骤,因为响应将在 JSON格式.
我正在使用 response
节点库发出一个 http 请求,我正在尝试递归调用它(如果用户在某一天进行了提交,请检查前一天。如果没有,请计数获得连胜的所有日子)。
问题是那行
const githubResponse = await request(options);
吐出错误
Unexpected token o in JSON at position 1
await request(options)
似乎没有 return 我期待的 JSON GitHub API 响应,而是 githubResponse
似乎成为我无法使用的对象。我猜我使用 async/await
不当,但我不确定如何解决它。
async function checkUserCommitForDate(user, date) {
const options = {
url: `https://api.github.com/search/commits?q=author:${user}+author-date:${date}`,
headers: {
'User-Agent': 'request',
'Accept': 'application/vnd.github.cloak-preview'
}
};
const githubResponse = await request(options)
// I get an error on the next line
if (JSON.parse(githubResponse).total_count > 0) {
const previousDaysDate = moment(date).subtract(1, 'day').format('YYYY-MM-DD');
let streakCounter = await checkUserCommitForDate(user, previousDaysDate);
streakCounter++;
console.log('streakCounter', streakCounter);
return streakCounter;
} else {
return 0;
}
}
更新:这似乎不是一个承诺,所以我需要以不同的方式格式化它(作为回调)。当我尝试这个时:
async function checkUserCommitForDate(user, date) {
const options = {
url: `https://api.github.com/search/commits?q=author:${user}+author-date:${date}`,
headers: {
'User-Agent': 'request',
'Accept': 'application/vnd.github.cloak-preview'
}
};
request(options, async function (error, response, body) {
console.log('error:', error); // Print the error if one occurred
if (JSON.parse(body).total_count > 0) {
const previousDaysDate = moment(date).subtract(1, 'day').format('YYYY-MM-DD');
let streakCounter = await checkUserCommitForDate(user, previousDaysDate);
streakCounter++;
console.log('streakCounter', streakCounter);
return streakCounter;
} else {
return 0;
}
});
}
行
let streakCounter = await checkUserCommitForDate(user, previousDaysDate);
成为问题,因为 streakCounter
未定义,使日志 NaN
.
我使用这里的 promisify example 将其转换为这个并且成功了!
async function checkUserCommitForDate(user, date) {
const options = {
url: `https://api.github.com/search/commits?q=author:${user}+author-date:${date}`,
headers: {
'User-Agent': 'request',
'Accept': 'application/vnd.github.cloak-preview'
}
};
const githubResponse = await promisify(request)(options);
if (JSON.parse(githubResponse.body).total_count > 0) {
const previousDaysDate = moment(date).subtract(1, 'day').format('YYYY-MM-DD');
let streakCounter = await checkUserCommitForDate(user, previousDaysDate);
streakCounter++;
console.log('streakCounter', streakCounter);
return streakCounter;
} else {
return 0;
}
}
function promisify(fn) {
return function (...args) {
return new Promise((resolve, reject) => {
fn(...args, (err, result) => {
if (err) return reject(err);
resolve(result);
});
});
};
};
如评论中所述request uses callbacks instead of returning a promise and you dont really need to promisify it by yourself since there's already a pacakge for that called request-promise。
在您的代码中使用它应该直接与 async/await
如果升级到 Node 8 LTS,那么原生 util.promisfy 可以如下使用:
const { promisify } = require('util')
const request = promisify(require('request'))
async function checkUserCommitForDate(user, date) {
const options = {
url: `https://api.github.com/search/commits?q=author:${user}+author-date:${date}`,
headers: {
'User-Agent': 'request',
'Accept': 'application/vnd.github.cloak-preview',
'json':true
}
};
try{
const githubResponse = await request(options);
if (githubResponse.body.total_count > 0) {
const previousDaysDate = moment(date).subtract(1, 'day').format('YYYY-MM-DD');
let streakCounter = await checkUserCommitForDate(user, previousDaysDate);
streakCounter++;
console.log('streakCounter', streakCounter);
return streakCounter;
} else {
return 0;
}
}
catch(err){
console.error(err)
return 0;
}
}
在 选项 中使用 json:true 将减少另一个解析步骤,因为响应将在 JSON格式.