0

I have this function:

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)
            });
        })
    })
}

I would like to promisify it so that I can call:

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

how can I achieve this? any help would be greatly apprectiated!

  • Start by returning a promise from `remove`… then [stop using `forEach`](https://stackoverflow.com/a/37576787/1048572) – Bergi Jul 13 '21 at 20:05

1 Answers1

1

You should:

  • return each promise that is created in a callback.
  • map the array of promises that you get from the recursive calls (instead of forEach) and pass that array to Promise.all
  • flatten the promise chain, avoiding nested then callbacks.
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)
        }));
    });
}

Things may become easier to read when using async await syntax:

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)));
}
trincot
  • 317,000
  • 35
  • 244
  • 286