关于javascript:“.then(function(a){return a;})”是否为承诺的无操作?

Is “.then(function(a){ return a; })” a no-op for promises?

我正在阅读有关Bookshelf的本教程。 Bookshelf使用Bluebird承诺。 有很多例子看起来像这样:

1
2
3
4
5
6
7
8
var getEvents = function(participantId) {  
  return new models.Participant()
    .query({where: {id: participantId}})
    .fetch({withRelated: ['events'], require: true})
    .then(function(model) {
      return model;
    });
};

我对承诺仍然不满意,但从我到目前为止所学到的东西看起来很奇怪。 我的问题是,上面的函数与直接返回fetch()并且不使用最终的then()完全相同:

1
2
3
4
5
var getEvents = function(participantId) {  
  return new models.Participant()
    .query({where: {id: participantId}})
    .fetch({withRelated: ['events'], require: true});
};

也就是说,它仍然做同样的事情,返回相同的承诺,可以以相同的方式调用,等等?

根据我的理解,传递给then的函数的参数获取链中前一个promise的返回值。 所以,在我看来,.then(function (a) { return a; })一般只是一个无操作。 对?

如果它们不一样,有什么区别? 发生了什么,为什么作者这样写呢?


It seems to me like .then(function (a) { return a; }) is just a no-op. Right?

Yes.1

它没用,应该省略。

What's going on and why did the author write it that way?

这是一个大错。 或者作者不理解承诺。

1: If they aren't the same, what's the difference?

与往常一样,有一些边缘情况。 真的很奇怪。 没有人应该使用(没有广泛的评论):
a)它返回一个新的promise实例,一个不同的对象,以避免共享。 但是,.then()也是如此。
b)再次测试a的可测性。 如果它自实现以来突然成为一种承诺,那么它现在将被等待。 这当然很糟糕。


Bergi的回答是正确的,但只是为了证明一个不是无操作的案例,这是一个人为的例子,它不是一个无操作:

1
2
3
4
o = {};
Promise.resolve(o).then(o => o.then = () => {}); // make thenable
Promise.resolve(o).then(console.log); // logs the object
Promise.resolve(o).then(x => x).then(console.log); // doesn't log the object

一般来说,不要做then(function(a) { return a; })