什么是幂等运算?


当前回答

只是想提出一个真实的用例来证明幂等性。在JavaScript中,假设你定义了一堆模型类(就像MVC模型一样)。它的实现方式通常是这样的(基本示例):

function model(name) {
  function Model() {
    this.name = name;
  }

  return Model;
}

然后你可以像这样定义新的类:

var User = model('user');
var Article = model('article');

但如果你试图通过模型(' User ')从代码的其他地方获取User类,它会失败:

var User = model('user');
// ... then somewhere else in the code (in a different scope)
var User = model('user');

这两个User构造函数是不同的。也就是说,

model('user') !== model('user');

为了让它是幂等的,你只需要添加一些缓存机制,像这样:

var collection = {};

function model(name) {
  if (collection[name])
    return collection[name];

  function Model() {
    this.name = name;
  }

  collection[name] = Model;
  return Model;
}

通过添加缓存,每次你建模('user')它都是同一个对象,所以它是幂等的。所以:

model('user') === model('user');

其他回答

任何操作,每n个结果都会产生与第1个结果值匹配的输出。例如,-1的绝对值是1。-1的绝对值的绝对值是1。-1绝对值的绝对值的绝对值等于1。等等。请参见:什么时候使用递归是非常愚蠢的?

幂等性意味着应用一次操作或应用多次操作具有相同的效果。

例子:

乘以0。无论你做多少次,结果仍然是零。 设置布尔标志。不管你做了多少次,旗帜都不会动摇。 从数据库中删除具有给定ID的行。如果你再试一次,排还是消失了。

对于纯函数(没有副作用的函数),幂等性意味着f(x) = f(f(x)) = f(f(f(x)))) = ......)) = f(f(f(f(x)))) = ......))对于x的所有值

对于有副作用的函数,幂等性进一步意味着在第一次应用后不会引起额外的副作用。如果愿意,可以将世界的状态视为函数的附加“隐藏”参数。

请注意,在有并发操作的情况下,您可能会发现您认为是幂等的操作不再是幂等的(例如,在上面的示例中,另一个线程可以取消布尔标志的值)。基本上,当你有并发性和可变状态时,你需要更仔细地考虑幂等性。

在构建健壮系统时,幂等性通常是一个有用的性质。例如,如果存在从第三方接收重复消息的风险,则将消息处理程序用作幂等操作,以便消息效果只发生一次,这是很有帮助的。

对于工作流管理器(如Apache workflow),如果管道中的幂等操作失败,系统可以自动重试该任务而不影响系统。即使日志发生了变化,这也很好,因为您可以看到事件。

在这种情况下,最重要的是您的系统可以重试失败的任务,并且不会弄乱管道(例如,每次重试都在表中添加相同的数据)

幂等运算即使调用多次也会产生相同状态的结果,前提是传入相同的参数。

my 5c: In integration and networking the idempotency is very important. Several examples from real-life: Imagine, we deliver data to the target system. Data delivered by a sequence of messages. 1. What would happen if the sequence is mixed in channel? (As network packages always do :) ). If the target system is idempotent, the result will not be different. If the target system depends of the right order in the sequence, we have to implement resequencer on the target site, which would restore the right order. 2. What would happen if there are the message duplicates? If the channel of target system does not acknowledge timely, the source system (or channel itself) usually sends another copy of the message. As a result we can have duplicate message on the target system side. If the target system is idempotent, it takes care of it and result will not be different. If the target system is not idempotent, we have to implement deduplicator on the target system side of the channel.