2017-10-20 219 views
0

我使用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,當我解析它時,我得到一個對象,但我仍然沒有返回數字,因爲有一個新問題。 –

回答

2

至於說在評論request使用回調,而不是返回一個承諾,你並不真正需要自己因爲已經有是爲調用request-promise一個pacakge到promisify它。

在代碼中使用它應該直接開箱與async/await

1

我用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

謝謝恩裏克!如果你想用它創建一個答案,我會把它標記爲正確的。 –

1

如果要升級到節點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格式。