首页 > 解决方案 > Promise.all 的上限是多少?

问题描述

最近我在解决大量承诺时遇到以下错误:

RangeError:传递给 Promise.all 的元素过多

我找不到有关 MDN 或 ECMA-262 限制的任何信息。

标签: node.jses6-promise

解决方案


根据源码对象Promise的V8/V8错误码TooManyElementsInPromiseAll

  T(TooManyElementsInPromiseAll, "Too many elements passed to Promise.all")

有这个限制。对于 Promise.all,即我们拥有的 C++ PromiseAll,有一个 and 的概念MaximumFunctionContextSlotskPromiseAllResolveElementCapabilitySlot这里源代码中最有趣的东西:

// TODO(bmeurer): Move this to a proper context map in contexts.h?
  // Similar to the AwaitContext that we introduced for await closures.
  enum PromiseAllResolveElementContextSlots {
    // Remaining elements count
    kPromiseAllResolveElementRemainingSlot = Context::MIN_CONTEXT_SLOTS,

    // Promise capability from Promise.all
    kPromiseAllResolveElementCapabilitySlot,

    // Values array from Promise.all
    kPromiseAllResolveElementValuesArraySlot,

    kPromiseAllResolveElementLength
  };

我希望看到像这里这样的错误抛出

ThrowTypeError(context, MessageTemplate::TooManyElementsInPromiseAll);

是引发TooManyElementsInPromiseAll错误的代码。感谢克拉伦斯为我指明了正确的方向!

BIND(&too_many_elements);
  {
    // If there are too many elements (currently more than 2**21-1), raise a
    // RangeError here (which is caught directly and turned into a rejection)
    // of the resulting promise. We could gracefully handle this case as well
    // and support more than this number of elements by going to a separate
    // function and pass the larger indices via a separate context, but it
    // doesn't seem likely that we need this, and it's unclear how the rest
    // of the system deals with 2**21 live Promises anyways.
    Node* const result =
        CallRuntime(Runtime::kThrowRangeError, native_context,
                    SmiConstant(MessageTemplate::kTooManyElementsInPromiseAll));
    GotoIfException(result, &close_iterator, var_exception);
    Unreachable();
  }

这个限制的检查在这里

// Check if we reached the limit.
    TNode<Smi> const index = var_index.value();
    GotoIf(SmiEqual(index, SmiConstant(PropertyArray::HashField::kMax)),
           &too_many_elements);

所以kMax应该解决线索!


推荐阅读