在路线中苦苦挣扎 - NodeJS

时间:2018-05-14 12:29:42

标签: node.js asynchronous

在我的nodejs后端我有一条删除产品的路线。由于用户可以上传与产品关联的图像,因此也需要删除相应的图像。但我很难做到这一点。

我的nodejs:

productRoutes.route('/delete/:id').get(function (req, res) {
    const id = req.params.id;
    Product.find({_id: id}).select('name').exec().then(product => {
        var name = product[0].name;
        rimraf('uploads/imgs/' + name, function () {
            console.log('uploads/imgs/' + name + ' deleted');
        });
    });
    Product.remove({_id: id})
        .exec()
        .then(result => {
            res.status(200).json(result);
        })
        .catch(err => {
            res.status(500).json({
                error: err
            });
        });
});

我首先搜索必须删除的产品名称。然后我用rimraf删除它的文件夹。

然后必须删除产品。现在我知道我做错了因为NodeJS的异步性。并且会出现一个错误,即name变量未定义,因为NodeJS是异步的。

但我真的很难以正确的方式做到这一点。你们能帮忙吗?

3 个答案:

答案 0 :(得分:1)

在这种情况下,您始终可以使用Promisesasync/await的概念。这些概念应该存在,记住node.js本质上是异步,有时,可能需要同步性质。如果您必须同步执行的操作是2或3(最好坚持2),那么使用嵌套回调就可以了。但是,更多嵌套回调产生了callback hell的概念。因此,您的目标可能会得到满足,但代码比以往更加可怕。

最佳做法 -

尽可能使用Promises -

new Promise((resolve, reject) => {
    // Product.find(... goes here.
    /* inside the callback of Product.find, if error is encountered, do - 
       reject(err);
    */
     /* else, if everything works fine - 
        resolve(data);
     */
}).then((data) => {
     // Product.remove goes here
}).catch((err) => {
     // error handling goes here
});

您还可以使用async/await功能来实现此目的。我在上面提到的链接中清楚地描述了该方法。

希望这有帮助。

答案 1 :(得分:1)

如果您使用将文档查找和删除结合到一个步骤中的findOneAndRemove方法,这会更容易:

productRoutes.route('/delete/:id').get(function (req, res) {
    const id = req.params.id;
    Product.findOneAndRemove({_id: id}, {select: 'name'}, (err, doc, result) => {
        if (err) {
            res.status(500).json({
                error: err
            });        
        }
        else if (doc) {
            rimraf('uploads/imgs/'+ name, function(){
                console.log('uploads/imgs/'+name + ' deleted');
                res.status(200).json(result);
            });    
        }
        else {
            // Don't forget to handle the "id not found" case
            res.send(404);
        }
    });
});

答案 2 :(得分:0)

回调让它变得更容易:

  

在每个方法调用之后,我使用回调,有时可能很乏味,但它更具可读性

在每个方法传递一些过滤后的数据后,让它为数据

Product.find({_id: id},(err,data)=>{
      if(err)throw err;
      else{
          data.select('name',(err,newData)=>{
            if(err)throw err;
            var name= newData[0].name;
            //your product will be the final filtered data 
            //you got the idea further you can proceed 
           }
           )
      }
})                   

与promises,exec,async等待相比,我发现这更容易和可维护 请记住,每种方法都会过滤数据,因此请调用给定的数据特定方法。希望你得到它,需要很多时间来写答案,特别是如果你是新来的PLZ试着理解我写的东西谢谢