JavaScript - Передача функции обратного вызова внутри функции, вызывающей себя
Я пытаюсь передать callback
функция внутри self-invoking function
в JavaScript, но я получаю "неопределенный", когда done
Функция выполнена.
Я прочитал этот ответ, чтобы написать этот код ниже:
function done() {
console.log(dateFilter.getI());
console.log(dateFilter.getF());
}
var dateFilter = (function(callback) {
var _dInicio = new Date(), _d = new Date(),
_dFim = new Date(_d.setMonth(new Date().getMonth() - 1));
return {
getI: function() { return _dInicio; },
getF: function() { return _dFim; },
setI: function(d) { _dInicio = d; },
setF: function(d) { _dFim = d; }
}, callback();
})(done);
Может быть, я неправильно использую оператор запятой, но я думаю, что это должно работать. Кто-то может указать мне, где я что-то неправильно понимаю?
3 ответа
Вы звоните done
функция после return
Дальше, ты не сдаешь парам dateFilter
,
return { -> return before calling callback `function`.
getI: function() { return _dInicio; },
getF: function() { return _dFim; },
setI: function(d) { _dInicio = d; },
setF: function(d) { _dFim = d; }
}, callback( );
^
|_ Calling callback without param `dateFilter`
Посмотрите на этот фрагмент кода
function done(dateFilter) {
console.log(dateFilter.getI());
console.log(dateFilter.getF());
}
(function(callback) {
var _dInicio = new Date(),
_d = new Date(),
_dFim = new Date(_d.setMonth(new Date().getMonth() - 1));
callback({
getI: function() {
return _dInicio;
},
getF: function() {
return _dFim;
},
setI: function(d) {
_dInicio = d;
},
setF: function(d) {
_dFim = d;
}
});
})(done);
Увидеть? сейчас печатает значения.
Две причины этого не могут работать:
- Вы возвращаете результат
callback
с оператором запятой, ноdone
ничего не возвращает - Вы пытаетесь использовать
dateFilter
во время инициализации IIFEdateFilter
- ему еще не присвоено возвращаемое значение
Нет абсолютно никаких причин использовать обратный вызов с IIFE. Просто пиши
var dateFilter = (function() {
var _dInicio = new Date(), _d = new Date(),
_dFim = new Date(_d.setMonth(new Date().getMonth() - 1));
return {
getI: function() { return _dInicio; },
getF: function() { return _dFim; },
setI: function(d) { _dInicio = d; },
setF: function(d) { _dFim = d; }
};
}());
console.log(dateFilter.getI());
console.log(dateFilter.getF());
Ты действительно близко. Ваше предположение об операторе запятой верно. И я думаю, что есть лучший способ подключить done()
обратный вызов, так что код немного более устойчив, и порядок, в котором все происходит, немного яснее.
Во-первых, давайте посмотрим на return
заявление. Все операторы return делают две вещи (оценивают возвращаемое значение, затем возвращают его), но из-за запятой этот выполняет три в следующем порядке:
- Оценка литерала объекта
{ getI:... }
- оценки
callback()
, что означает вызовcallback()
- возвращая возвращаемое значение
callback()
, так как оператор запятой возвращает свой второй операнд.
Итак, обратите внимание, что callback()
на самом деле вызывается до того, как ваша функция возвращается, поэтому это происходит до dateFilter
имеет значение. (И даже если бы оно имело значение, это было бы возвращаемое значение из callback()
, который не определен.)
И я думаю, что здесь есть еще один аспект вашего кода, который, я думаю, стоит посмотреть. Обратные вызовы обычно принимаютпараметры. Самый простой способ думать об этом: вместо того, чтобы возвращать значение, вы передаете его обратному вызову.
В общем, код легче читать и отлаживать, если вы передаете параметры вместо побочных эффектов общих переменных.
Я только что сделал одно изменение в вашем коде, и он работает:
function done(dateFilter) {
console.log(dateFilter.getI());
console.log(dateFilter.getF());
}
(function(callback) {
var _dInicio = new Date(), _d = new Date(),
_dFim = new Date(_d.setMonth(new Date().getMonth() - 1));
callback({
getI: function() { return _dInicio; },
getF: function() { return _dFim; },
setI: function(d) { _dInicio = d; },
setF: function(d) { _dFim = d; }
});
})(done);
Итак, что я сделал?
- Вместо побочных эффектов
dateFilter
значение, я передаю это непосредственноcallback
,
Это означает, что в return
заявление, и нет необходимости побочных эффектов dateFilter
глобальное значение. (dateFilter
теперь параметр для done
isntead.)
Я надеюсь, что это проясняет ситуацию для вас. Ура!