Привязка функции обратного вызова при использовании Async Waterfall

1

Я пытался какое-то время найти хорошее решение для абстрагирования функции из функции async waterfall (async library) (чтобы сохранить мой код DRY), но я все время получал ошибку, говоря, что cb не был определен. Кроме того, при передаче только this для bind функция, которая была определена как async была областью, а также при передаче cb. В конце концов, я нашел решение, которое работает (добавление cb как функция для this объекта), но оно выглядит немного грязным, и, вероятно, лучший способ сделать это. Какие-либо предложения?:

// 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);
        });
    },
...
}

Примечание: код реорганизован в файл служб для тестирования модулей и бережливых контроллеров (с использованием подхода MVC)

Теги:
callback
asynchronous

1 ответ

0

Вы не должны нуждаться в каком-либо рефакторинге, async уже является абстрактным. Просто снимите callbackHandler и передайте cb прямо в вашу функцию:

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

Однако вы получаете гораздо более простой код, если вы просто async.js от async.js здесь и async.js обещания:

// 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
)
…

// 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 должна быть анонимная функция
  • 0
    @ timhc22 Нет, нет, почему ты так думаешь? cb - это функция с двумя параметрами, и это все, что требуется.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню