什么是幂等运算?


当前回答

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

其他回答

理解幂等运算的一个好例子可能是用远程钥匙锁汽车。

log(Car.state) // unlocked

Remote.lock();
log(Car.state) // locked

Remote.lock();
Remote.lock();
Remote.lock();
log(Car.state) // locked

锁是一个幂等运算。即使每次运行上锁都有一些副作用,比如眨眼,但不管你运行多少次上锁操作,汽车仍然处于相同的上锁状态。

假设客户端向“IstanceA”服务发出请求,该服务处理请求,将其传递给DB,并在发送响应之前关闭。因为客户端没有看到它被处理,它将重试相同的请求。负载均衡器将请求转发到另一个服务实例“InstanceB”,该服务实例将对相同的DB项进行相同的更改。

我们应该使用幂等符号。当客户端向服务发送请求时,它应该有某种类型的请求id,可以保存在DB中,以显示我们已经执行了请求。如果客户端重试请求,“InstanceB”将检查requestId。由于特定的请求已经被执行,因此它不会对DB项进行任何更改。这种请求叫做幂等请求。因此,我们多次发送相同的请求,但不会做任何更改

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

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

只是想提出一个真实的用例来证明幂等性。在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');

无论调用该操作多少次,结果都是相同的。