Promise.all() 为何会触发 Array.prototype.then 如果已定义?

huangapple go评论169阅读模式
英文:

Why does Promise.all() tigger Array.prototype.then if defined?

问题

以下是翻译好的内容:

拥有以下代码片段...

const array = [
  Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)
];

Array.prototype.then = function () {
  console.log('为什么会触发这个?');
}

Promise.all(array)
  .then(result => console.log(result))

为什么 Promise.all() 单独调用了我的 Array 上的 .then() 原型函数?

当然,它必须为数组中的每个元素调用 .then()。这是显而易见的。但这样做的目的是什么?

此行为发生在 V8 上

需要考虑的是: 如果将 Promise.all() 更改为 Promise.race(),则不会发生这种情况。

我并不是在说这是一个错误。我只是想了解原因。如果你能引用 EcmaScript 规范中的答案,我会非常感激。

更新:
我知道 Promise.all() 返回一个包装在 Promise 中的数组。这也是显而易见的。如果你删除 .then(),如下所示...

Promise.all(array)

它仍然会执行 .then() 方法。

英文:

Having the following pice of code...

const array = [
  Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)
];

Array.prototype.then = function () {
  console.log('Why does this gets triggered?');
}

Promise.all(array)
  .then(result => console.log(result))

Why does Promise.all() by itself calls my .then() proto function on the Array?

Of course it must call .then() for each of the elements in the array. That’s obvious. But what is the purpose of doing it over the Array itself?

This behavior is happening on V8

To consider: If you change Promise.all() to Promise.race() this does not happen.

I'm not saying this is a mistake. I just want to understand the reason. If you can quote the EcmaScript specification on the answer I would really appreciate.

Update:
I know Promise.all() returns an array but wrapped on a promise. That is obvious too. If you remove the .then() like...

Promise.all(array)

it still executes the .then()method.

答案1

得分: 3

当调用resolve()时,如果传递给它的值具有指向函数的.then属性,正常的Promise机制将调用该函数。在这种情况下,在Promise.all()内部,解析源数组中的每个Promise时都会构建一个解析值数组。当完成时,Promise.all()内部将调用自己的resolve(),并传入已解析值的数组。

那个数组也将继承自Array原型的.then()值。因此,该resolve()调用将像任何其他Promise解析一样调用.then()方法。

Promise规范中的resolve()

英文:

When a resolve() is called, and the value passed to it has a .then property that refers to a function, the normal Promise mechanism will invoke that function. In this case, internal to Promise.all() an array of resolution values is built as each Promise in the source array is resolved. When that finishes, the innards of Promise.all() will call its own resolve(), passing in the array of resolved values.

Well that array will also have a .then() value, inherited from the Array prototype. Thus that resolve() call will invoke the .then() method just like any other Promise resolution would.

Promise resolve() in the spec

huangapple
  • 本文由 发表于 2020年1月7日 00:35:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/59615739.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定