njs_promise_race(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
    njs_index_t unused)
{
    int64_t                      length;
    njs_int_t                    ret;
    njs_value_t                  *promise, *iterator, resolve;
    njs_promise_iterator_args_t  pargs;

    promise = njs_argument(args, 0);
    iterator = njs_arg(args, nargs, 1);

    pargs.capability = njs_promise_new_capability(vm, promise);
    if (njs_slow_path(pargs.capability == NULL)) {
        return NJS_ERROR;
    }

    ret = njs_value_property(vm, promise, njs_value_arg(&string_resolve),
                             &resolve);
    if (njs_slow_path(ret != NJS_OK)) {
        return ret;
    }

    if (njs_slow_path(!njs_is_function(&resolve))) {
        njs_type_error(vm, "resolve is not callable");
        return NJS_ERROR;
    }

    ret = njs_object_length(vm, iterator, &length);
    if (njs_slow_path(ret != NJS_OK)) {
        return ret;
    }

    njs_memzero(&pargs.args, sizeof(njs_iterator_args_t));

    pargs.function = njs_function(&resolve);
    pargs.constructor = promise;

    pargs.args.value = iterator;
    pargs.args.to = length;

    ret = njs_object_iterate(vm, &pargs.args, njs_promise_perform_race_handler);
    if (njs_slow_path(ret == NJS_ERROR)) {
        return ret;
    }

    vm->retval = pargs.capability->promise;

    return NJS_OK;
}
njs_promise_race(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
    njs_index_t unused)
{
    int64_t                      length;
    njs_int_t                    ret;
    njs_value_t                  *promise, *iterator, resolve;
    njs_promise_iterator_args_t  pargs;

    promise = njs_argument(args, 0);
    iterator = njs_arg(args, nargs, 1);

    pargs.capability = njs_promise_new_capability(vm, promise);
    if (njs_slow_path(pargs.capability == NULL)) {
        return NJS_ERROR;
    }

    ret = njs_value_property(vm, promise, njs_value_arg(&string_resolve),
                             &resolve);
    if (njs_slow_path(ret != NJS_OK)) {
        return ret;
    }

    if (njs_slow_path(!njs_is_function(&resolve))) {
        njs_type_error(vm, "resolve is not callable");
        return NJS_ERROR;
    }

    ret = njs_object_length(vm, iterator, &length);
    if (njs_slow_path(ret != NJS_OK)) {
        return ret;
    }

    njs_memzero(&pargs.args, sizeof(njs_iterator_args_t));

    pargs.function = njs_function(&resolve);
    pargs.constructor = promise;

    pargs.args.value = iterator;
    pargs.args.to = length;

    ret = njs_object_iterate(vm, &pargs.args, njs_promise_perform_race_handler);
    if (njs_slow_path(ret == NJS_ERROR)) {
        return ret;
    }

    vm->retval = pargs.capability->promise;

    return NJS_OK;
}