AngularJS:如何避免匿名承诺处理程序

时间:2014-11-25 12:28:03

标签: javascript angularjs promise anonymous-function angular-promise

最近我的客户已选择关注John Papa's AngularJS Style Guide *。

我目前正在浏览当前的代码库,以确保不会留下任何匿名函数。但是,我遇到了一些需要处理程序的情况,这些处理程序需要的参数不是由promise的响应/拒绝设置的,而是由另一个函数或param设置的。我已经尝试过在回调中传递这些参数,但我失败了。

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?

这里的目标是确保在函数中没有声明函数,以便在同一级别命名和声明每个函数。我们的目标是减少功能的长度,特别是使它们更易于测试。

请参阅上面的代码摘录,如果您有任何建议,请告诉我。请记住,这不是我们使用的代码,而是一个模拟函数如何工作的最小原型。

如果有帮助,请参阅the code in github。在此先感谢您的帮助。

*不要就风格指南进行宗教辩论,这不是这个问题的主题。

2 个答案:

答案 0 :(得分:2)

您可以使用Function.prototype.bind

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

然后,您的函数将被调用,就像您在选项1中执行onPromiseResolved(timestamp)一样。

有关详细信息,请参阅the docs

答案 1 :(得分:0)

您不能传递参数。您只需要在函数定义中声明它。

使用"外部"功能声明

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(…), …)