使用节点请求包递归地使用异步/等待

使用节点请求包递归地使用异步/等待

问题描述:

我使用response节点库发出http请求,并试图递归调用它(如果用户在某一天做了提交,请检查前一天。 ,计算所有的日子来获得连胜)。使用节点请求包递归地使用异步/等待

的问题是该行

const githubResponse = await request(options); 

吐出来的是错误

Unexpected token o in JSON at position 1 

await request(options)似乎并没有回到我期待的JSON API GitHub的响应,而是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

+0

您是否可以使用'request'模块,而不是'response'?如果是这样,它不会返回承诺,但会使用回调。 – alexmac

+0

什么是gitubResponse?你有没有试图解析之前console.log它? –

+0

在更新中,当我记录正文时,我得到JSON,当我解析它时,我得到一个对象,但我仍然没有返回数字,因为有一个新问题。 –

至于说在评论request使用回调,而不是返回一个承诺,你并不真正需要自己因为已经有是为调用request-promise一个pacakge到promisify它。

在代码中使用它应该直接开箱与async/await

我用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); 
      }); 
     }); 
    }; 
}; 
+2

已经有一个请求承诺(https://github.com/request/request-promise)模块来处理您的请求promisification –

+0

谢谢恩里克!如果你想用它创建一个答案,我会把它标记为正确的。 –

如果要升级到节点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格式。