Recently i got the following error while resolving a VERY large number of promises:
RangeError: Too many elements passed to Promise.all
I couldn't find any information regarding limits on MDN or ECMA-262.
According to the V8/V8 error code TooManyElementsInPromiseAll
of the source code objects Promise
T(TooManyElementsInPromiseAll, "Too many elements passed to Promise.all")
there is this limit. For the Promise.all i.e. the C++ PromiseAll we have there is a concept of MaximumFunctionContextSlots
and kPromiseAllResolveElementCapabilitySlot
, here it is the most interesting stuff from the source code:
// 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
};
I would expect to see a error throw like here
ThrowTypeError(context, MessageTemplate::TooManyElementsInPromiseAll);
Here it is the code that raise the TooManyElementsInPromiseAll
error. Thank to Clarence that pointed me in the right direction!
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();
}
The check of this limit it is here
// Check if we reached the limit.
TNode<Smi> const index = var_index.value();
GotoIf(SmiEqual(index, SmiConstant(PropertyArray::HashField::kMax)),
&too_many_elements);
so the kMax
should solve the clue!