AngularJS: Как избежать обработчиков анонимных обещаний

Недавно с моим клиентом мы решили следовать Руководству по стилю AngularJS Джона Папы*.

В настоящее время я прохожу текущую кодовую базу, чтобы удостовериться, что не осталось никакой анонимной функции. Однако я сталкиваюсь со случаем некоторых обработчиков обещаний, которые требуют параметров, установленных не ответом / отклонением обещания, а другой функцией или параметром. Я сделал несколько попыток передачи этих параметров в обратном вызове, но мне не удалось.

function testPromise() {
  setPromiseAsPending();

  var timestamp = new Date().toString();

  firstModel.callPromise()
  // option 1: use of anonymous functions. works, but not the aim.
    // .then(
    //   function () {
    //     onPromiseResolved(timestamp);
    //   },
    //   function () {
    //     onPromiseRejected(timestamp);
    //   }
    // )['finally'](setPromiseAsCompleted);

  // option 2: naming functions in context. works, but less than ideal in our context.
    .then(
      function onPromiseResolved() {
        secondModel.logPromiseResults('this promise has been resolved on ' + timestamp);
      },
      function onPromiseRejected() {
        secondModel.logPromiseResults('this promise has been rejected on ' + timestamp);
      }
    )['finally'](setPromiseAsCompleted);

  // option 3: passing functions as variables. not good: doesn't work, missing the parameter.
    // .then(
    //   onPromiseResolved,
    //   onPromiseRejected
    // )['finally'](setPromiseAsCompleted);

  // option 4: calling functions with parameters. not good: both functions called.
    // .then(
    //   onPromiseResolved(timestamp),
    //   onPromiseRejected(timestamp)
    // )['finally'](setPromiseAsCompleted);

  // option 5: how do i pass the parameter to only be used when the function is called?

Цель здесь - убедиться, что внутри функции не объявлено ни одной функции, чтобы каждая функция называлась и объявлялась на одном и том же уровне. Мы стремимся сократить длину функций, особенно чтобы сделать их более тестируемыми.

См. Фрагмент кода выше и дайте мне знать, если у вас есть предложение. Имейте в виду, что это не код, который мы используем, а минимальный прототип, имитирующий работу функции.

Смотрите код в github, если это вам поможет. Заранее спасибо за помощь.

* Не вступайте в религиозные дебаты по поводу руководства по стилю, это не предмет этого вопроса.

2 ответа

Вы могли бы использовать Function.prototype.bind:

.then(
   onPromiseResolved.bind(null, timestamp),
   onPromiseRejected.bind(null, timestamp)
)['finally'](setPromiseAsCompleted);

Тогда ваша функция будет вызываться так же, как если бы вы это сделали onPromiseResolved(timestamp) как в варианте 1.

Смотрите документы для получения дополнительной информации.

Вы не должны передавать параметр. Вам просто нужно объявить это в определении вашей функции.

Либо используйте "внешнее" объявление функции

function onPromiseResolved(timestamp) {
    secondModel.logPromiseResults('this promise has been resolved with ' + timestamp);
}
function onPromiseRejected(err) {
    secondModel.logPromiseResults('this promise has been rejected with ' + err);
}

….then(onPromiseResolved, onPromiseRejected)

или выражение именованной функции:

.then(function onPromiseResolved(timestamp) {
    secondModel.logPromiseResults('this promise has been resolved with ' + timestamp);
}, function onPromiseRejected(err) {
    secondModel.logPromiseResults('this promise has been rejected with ' + err);
})

Цель здесь - убедиться, что внутри функции не объявлено ни одной функции, чтобы каждая функция называлась и объявлялась на одном уровне.

Это довольно бесполезно. Иногда вам просто нужны замыкания (поскольку вы не хотите, чтобы все переменные были статическими глобальными переменными). Конечно, вы все равно можете их переместить и явно передать переменные замыкания в качестве аргументов:

function makeOnPromiseResolvedHandler(closurevars) {
    return function onPromiseResolved(timestamp) {
        secondModel.logPromiseResults('this promise has been resolved with ' + timestamp);
        // use closurevars in here
    };
}

….then(makeOnPromiseResolvedHandler(…), …)
Другие вопросы по тегам