JavaScript - Передача функции обратного вызова внутри функции, вызывающей себя

1

Я пытаюсь передать функцию callback внутри функции self-invoking function в JavaScript, но я получаю "undefined", когда 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);

Возможно, я неправильно использую оператор запятой, но я думаю, что это должно сработать. Кто-то может указать мне, где я что-то недопонимаю?

  • 0
    done ничего не возвращает. Вы хотя бы получаете логи для dateFilter?
Теги:
closures
self-invoking-function

3 ответа

3

Вы вызываете done функцию после return, далее вы не передаете param 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);

Увидеть? теперь печатает значения.

  • 0
    Я вижу, это работает, но таким образом я не могу получить доступ к внутренним функциям dateFilter из области действия готовой done function , могу ли я?
  • 0
    @AlexandreMiziara Я не понимаю. Какие внутренние функции?
Показать ещё 6 комментариев
2

Две причины этого не могут работать:

  • Вы возвращаете результат callback с помощью оператора запятой, но done не возвращает ничего
  • Вы пытаетесь использовать dateFilter во время инициализации dateFilter - он еще не присвоил возвращаемое значение

Нет абсолютно никакой причины использовать обратный вызов с 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());
  • 0
    На самом деле мне нужно выполнить функцию после того, как убедитесь, что dateFilter был выполнен, поэтому я попытался с помощью callback . Должен ли я использовать обещания вместо этого?
  • 1
    Здесь нет ничего асинхронного, поэтому простое размещение его после IIFE обеспечит его запуск.
Показать ещё 2 комментария
1

Ты действительно рядом. Ваша догадка о запятой правильная. И я думаю, что есть лучший способ подключить ваш обратный вызов done() чтобы код был более надежным, и порядок, в котором все происходит, немного яснее.

Во-первых, давайте посмотрим на оператор return. Все операторы return делают две вещи (оценивают возвращаемое значение, а затем возвращают его), но из-за запятой это делается тремя, в следующем порядке:

  1. Оценка объектного литерала { getI:... }
  2. оценка callback(), что означает вызов callback()
  3. возвращая возвращаемое значение 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 значения dateFilter я dateFilter его непосредственно для callback.

Это означает: нет оператора запятой в операторе return и нет необходимости влиять на глобальное значение dateFilter. (dateFilter теперь является параметром done isntead.)

Надеюсь, это прояснит вам все. Ура!

  • 0
    Это многое проясняет. Я не видел, как порядок вещей выполнялся раньше. Спасибо за Ваш ответ. Теперь я лучше понимаю, как обратный вызов и оператор запятой могут работать вместе.

Ещё вопросы

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