首页 > 解决方案 > 如何承诺一个foreach循环

问题描述

我有这个功能:

remove(data.toString())
function remove(node){
    Item.findByIdAndDelete(node).then(()=>{
        Item.find({parent: mongoose.Types.ObjectId(node)}).select('_id').then((d)=>{
            d.forEach(e => {
                remove(e._id)
            });
        })
    })
}

我想承诺它,以便我可以致电:

remove(data.toString()).then(()=>{console.log('done')})

我怎样才能做到这一点?任何帮助将不胜感激!

标签: javascriptloopsasynchronouspromise

解决方案


你应该:

  • 返回在回调中创建的每个承诺。
  • map您从递归调用(而不是forEach)中获得的承诺数组并将该数组传递给Promise.all
  • 扁平化承诺链,避免嵌套then回调。
function remove(node) {
    return Item.findByIdAndDelete(node).then(() => {
        return Item.find({parent: mongoose.Types.ObjectId(node)}).select('_id');
    }).then(d => {
        return Promise.all(d.map(e => {
            return remove(e._id)
        }));
    });
}

async await使用语法时,事情可能会变得更容易阅读:

async function remove(node) {
    await Item.findByIdAndDelete(node);
    let d = await Item.find({parent: mongoose.Types.ObjectId(node)}).select('_id');
    return Promise.all(d.map(e => remove(e._id)));
}

推荐阅读