Node.js: callback или deferred?

поработал немного в node.js и решил спросить у сообщества — какой подход лучше использовать: callback или deferred?

Собственно пример с callback:
var f1 = function(callback) {
    setTimeout(function() {
        callback(null, 'f1 done');
    }, 100);
};

var f2 = function(callback) {
    f1(function(err, data) {
        if (err) {
            callback(err);
            return;
        }
        // работает с data
        callback(null, 'f2 done');
    })
};

f2(function(err, data) {
    if (err) {
        //....
        return;
    }
    console.log(data);
});


Минусы:
1. мне нужно много раз анализировать err. (по сути в каждой функции).
2. по-хорошему нужно не просто вызывать callback(null, data); а дополнительно проверять typeof callback === function, что также вносить дополнительные сложности

Второй подоход — использовать deferred (например jquery)
var $ = require('jquery');
var f1 = function(callback) {
    var d = $.Deferred();
    setTimeout(function() {
        d.resolve('f1 done');
    }, 100);
    return d.promise();
};

var f2 = function() {
    return f1().pipe(function(data) {
        // работает с data
        return 'f2 done';
    });
};

f2().done(function(result) {
    console.log(result);
});


Плюс очевиден — мы можем в f2 обрабатывать только успешное выполнение f1, а ошибку передавать дальше и никаких заморочек с проверкой typeof callback
  • Вопрос задан
  • 9439 просмотров
Пригласить эксперта
Ответы на вопрос 2
Если я правильно понял вопрос, как удобно построить цепочку вызывающих себя через callback'и функций с передачей данных следующей функции, то с использованием async это пишется так:
var async = require('async');

async.waterfall([
	function(callback){
		setTimeout(function() {
			console.log('f1 done');
			callback(null, 'data from f1');
		}, 100);
	},
	function(data, callback){
		// работа с data
		// или расширение цепочки через функцию f3, которая по окончании работы вызовет callback
		// f3(callback);
		console.log('f2 done');
		callback(null, 'done');
	}
], function (err, result) {
	// result now equals 'done'
	if (err) {
		// единое место для отлова ошибок
	}
	console.log(result);
});
Ответ написан
Для таких случаев я у себя использую async.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы