对节点请求包

时间:2017-10-20 21:34:45

标签: node.js asynchronous recursion async-await node-request

我正在使用response节点库发出http请求,我试图以递归方式调用它(如果用户在某一天提交,请检查前一天。如果没有,请计数所有的日子,以获得连胜)。

问题在于行

const githubResponse = await request(options);

吐出错误

Unexpected token o in JSON at position 1

await request(options)似乎没有返回我期待的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

3 个答案:

答案 0 :(得分:2)

我从这里使用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);
            });
        });
    };
};

答案 1 :(得分:2)

正如评论request中所说,使用回调而不是返回承诺而你真的不需要自己宣传它,因为已经有一个叫做request-promise的版本。

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

开箱即用

答案 2 :(得分:1)

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