【问题标题】:Promise.all([ anotherPromise, anotherPromise ]) when nesting promises the parent is not blockingPromise.all([ anotherPromise, anotherPromise ]) 嵌套 promise 时,父级没有阻塞
【发布时间】:2026-01-17 19:30:01
【问题描述】:

在以下示例中,get_bc_templates()get_bc_template() 之前返回。

async get_bc_templates(mfpns, cnetDB, cb) {
    const templates = await Promise.all([mfpns.map(async item => await this.get_bc_template(item, cnetDB))]);
    if (cb) {
        console.log(`prints immediately. before get_bc_template`.green.bold, templates)
        return cb(200, templates.map(template => template.bigCommerce_object))
    }
}




async get_bc_template(mfpn, cnetDB, cb ?) {
    console.log('this logs after the get_bc_templates already returns', mfpn);
    let collective_product = {
        CNET_data: promised_data[1],
        JAX_data: JAX_data,
        suggested_retail: await this.calc_suggested_retail(JAX_data),
        }
    return collective_product;
}


我需要帮助来重写它,所以 get_bc_templates 返回一个 get_bc_template() => collective_product 数组(get_bc_template() 一次可以很好地工作)。

【问题讨论】:

    标签: javascript node.js typescript


    【解决方案1】:

    Promise.all 需要一个数组作为参数,你传递的是一个数组的数组: [mfpns.map(async item => await this.get_bc_template(item, cnetDB))]

    map 函数已经返回一个数组。所以,你所拥有的是一个数组内的一系列承诺:Promise.all([[promise, anotherPromise, ...]])

    因此Promise.all 将尝试仅等待数组,而不是内部的承诺。

    您应该删除 map 函数周围的数组括号:

    const templates = await Promise.all(mfpns.map(async item => await this.get_bc_template(item, cnetDB)));
    

    【讨论】:

    • 非常感谢。跟进 ==> get_bc_template 中的 console.log 会在正确的时间打印出正确的数据...但是父函数有 undefined foreach...有什么想法吗?
    • @Omar 我认为这可能与您尝试访问template.bigCommerce_object 的事实有关,这不是您在get_bc_template() 中返回的对象上定义的键。您在模板上拥有的唯一键是 CNET_dataJAX_datasuggested_retail
    【解决方案2】:

    您不是将一组承诺传递给Promise.all,而是传递一组数组(内部数组由map 构造,外部由[] 字面量构造)。你应该这样做

    async get_bc_templates(mfpns, cnetDB) {
        const templates = await Promise.all(mfpns.map(item => this.get_bc_template(item, cnetDB)));
        console.log(`prints immediately. before get_bc_template`.green.bold, templates)
        return templates.map(template => template.bigCommerce_object);
    }
    

    【讨论】:

    • 原谅我的迂腐,但是当它是一个只能包含一个数组的数组时,它可以称为 arrays 数组吗? :P
    • @Klaycon 迂腐的回答:是的,我们可以,如果我们引用类型而不是值。甚至 [] 也可能是一个数字数组,尽管它不包含一个数字 - 它与 [][[]] 不同,后者是一个承诺数组的数组。
    • 公平点,但是在像 javascript 这样类型可以变化的语言中,我认为准确引用它包含的内容是有意义的。