node-bing-api を使用したコードがあります。 これはエラーファーストで完全に機能しますが、Promises(およびawait
)を使用するように変換したいと思います。
ノード8とutil.promisify
を使用しています。以下のコードでは、Bing.web
は通常のエラーファーストコードであり、searchBing
は約束されたバージョンです。
var findParentDir = require('find-parent-dir'),
configDir = findParentDir.sync(__dirname, 'config.js'),
config = require(configDir+'config.js'),
util = require('util'),
log = console.log.bind(console),
Bing = require('node-bing-api')({ accKey: config.cognitiveServices.bingSearch }),
searchBing = util.promisify(Bing.web);
var start = async function(){
// This fails
// var searchResultsRaw = await searchBing('windows', {top: 5})
// log(searchResultsRaw)
// This works
Bing.web('windows', {top: 5}, function(err, searchResultsRaw){
log(searchResultsRaw)
})
};
start();
約束されたバージョンは次のように失敗します:
(node:1752) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): TypeError: this.searchVertical is not a function
これはnode-bing-api内のエラーです。しかし、util.promisify
は、元の関数と同じ引数を使用して、オプションを実際のbing.web
にシームレスに渡すべきではありませんか?
約束したときにこの関数が機能しないのはなぜですか?
私は自分の約束したバージョンを作ることができます-それは機能します-しかし私はむしろ余分なコードを作成したくないことに注意してください:
var searchBing = function(){
return new Promise(function(resolve, reject) {
Bing.web('windows', {top: 5}, function(err, searchResults){
if ( err ) {
reject(err)
return
}
resolve(searchResults)
})
})
}
おそらくコンテキストが欠落しています。関数Bing.web
は本体でthis
を使用していますが、util.promisify
を使用する場合はBing
にバインドされていません。
次の方法で明示的にバインドする必要があります。
searchBing = util.promisify(Bing.web.bind(Bing));