web-dev-qa-db-ja.com

関数は機能しますが、util.promisify()を使用すると失敗しますか?

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)
    })
  })
}
17
mikemaccana

おそらくコンテキストが欠落しています。関数Bing.webは本体でthisを使用していますが、util.promisifyを使用する場合はBingにバインドされていません。

次の方法で明示的にバインドする必要があります。

searchBing = util.promisify(Bing.web.bind(Bing));
29
rbaumier