2017-05-31 20 views
1

私はしばらくの間、非同期ウォーターフォール(非同期ライブラリ)関数(コードDRYを維持する)から関数を抽象化するための良い解決策を見つけようとしていましたが、 cbが定義されていないと言っています。また、thisbindに渡すと、asyncが定義された関数がスコープであり、cbも渡します。 最終的に、私は解決しました(cbを関数としてthisオブジェクトに追加しました)、少しばかり見えますが、おそらくもっと良い方法があります。任意の提案?:Async Waterfallを使用してコールバック関数をバインドする

// registerController.js 
const async = require('async'); 
const registerService = require('../services/register'); 

// Api endpoint code 
... 

// is there a better way than (this.cb = cb) 
let callbackHandler = (err, res) => { 
    if (err) this.cb(err); 
    this.cb(null, res); 
}; 

// asynchronously perform registration 
async.waterfall([ 
    (cb) => { 
     registerService.createAccount(username, email, callbackHandler.bind(this.cb = cb)); 
    }, 
    (res, cb) => { 
     registerService.doSomethingElse(domain, callbackHandler.bind(this.cb = cb); 
    }, 
.... 

// registerService.js 
module.exports = { 

    createAccount: (username, email, callback) => { 
     httpService.request({ 
      host: myHost, 
      method: 'POST', 
      path: '/api/signup', 
      body: { 
       username, 
       email 
      } 
     }).then((res) => { 
      return callback(null, res); 
     }).catch((err) => { 
      return callback(err); 
     }); 
    }, 
... 
} 

注:ユニットテストの目的とリーンコントローラのServicesファイルにリファクタリングコード(MVCのアプローチを取って)

+0

これはうんざりですが、うまくいかないことがあります。もし私が試してみたので、callbackHandler.bind({cb:cb}) ' – Bergi

+0

@Bergiを実行したいと思うかもしれませんが、 – timhc22

答えて

0

あなたはどのリファクタリングを必要とすることになっていない、asyncはすでにです抽象。ただ、callbackHandlerをドロップすると、あなたの関数に直接cbを渡す:

// registerController.js 
const registerService = require('../services/register'); 

// Api endpoint code 
… 
registerService.createAccount(username, email) 
.then(res => 
    registerService.doSomethingElse(domain) // supposed to return a promise as well 
) 
… 

async.waterfall([ 
    (cb) => { 
     myService.createAccount(fullName, email, cb); 
    }, 
    (res, cb) => { 
     myService.doSomethingElse(domain, cb); 
    }, 
    … 
], …); 

は、しかし、あなたはちょうどここにasync.jsを放棄し、受け入れる場合は約束はるかに簡単なコードを取得

// registerService.js 
exports.createAccount = (username, email) => { // no callback 
    return httpService.request({ 
// ^^^^^^ returns the promise 
     host: myHost, 
     method: 'POST', 
     path: '/api/signup', 
     body: { 
      username, 
      email 
     } 
    }); 
}; 
… 
+0

を使って解決しようとします。ただし、cbは匿名関数でなければなりません。 – timhc22

+0

@ timhc22いいえ、それはなぜそう思いますか? 'cb'は2つのパラメータを持つ関数であり、それがすべて必要なものです。 – Bergi

+0

私はこの例を更新しました。私は非同期の動作方法を誤解していますか? – timhc22

関連する問題