【问题标题】:How to write synchronous function in Node.js如何在 Node.js 中编写同步函数
【发布时间】:2016-07-02 11:32:36
【问题描述】:

我是 Node.js 的新手,我正在努力处理异步调用。

在下面的代码中,我有一个提要数组,例如 (1,2,3..)。每个提要可以包含多个图像,现在我想从文件夹和数据库中删除图像。

到目前为止我做了什么:

for(var i=0; i<feedArr.length; i++){
    var feedId = feedArr[i].feedid;
    var listFeedImageQuery  = "select imageUrl from feedImages where feedId='"+feedId+"'";
    var deleteFeedImagesQuery = "delete from feedImages where feedId='"+feedId+"'";
    model.client.query(listFeedImageQuery,function(err,result){
        if(result.rows.length > 0){
            for(var j=0; j<result.rows.length; j++){
                fs.unlink(result.rows[j].imageurl, function(err) {
                    if(err)
                        console.log(err);
                });
            }
            model.client.query(deleteFeedImagesQuery,function(err,result){
                if(err)
                    console.log(err)
                else
                    console.log(feedId +' were removed'); // last feedId only gets removing from database
            });
        }   
    });
}

在这里,我可以从图像存储文件夹中删除图像,但无法从数据库中删除记录。只有最后一个提要记录被删除。其余的 feedImage 记录在数据库中。

我研究了一些关于异步模块的东西,但我不知道如何将它应用到这个问题上。

【问题讨论】:

标签: node.js express asynchronous


【解决方案1】:

这是从“标准”框架切换到回调框架时的常见问题。

它是这样工作的,首先它同步运行这个

for(var i=0; i<feedArr.length; i++){
    var feedId = feedArr[i].feedid;
    var listFeedImageQuery  = "select imageUrl from feedImages where feedId='"+feedId+"'";
    var deleteFeedImagesQuery = "delete from feedImages where feedId='"+feedId+"'";
    model.client.query(listFeedImageQuery,function(err,result){
        //to be executed later
    });
}

方法model.client.query在每个周期被推送到“异步调用堆栈”,因此在所有这些查询执行的那一刻,feedId等于feedArr[feedArr.length-1].feedid

一个简单的解决方法是用参数将它包裹在方法周围,然后立即调用它们。

for(var i=0; i<feedArr.length; i++){        
    (function(feedId) {
       var listFeedImageQuery  = "select imageUrl from feedImages where feedId='"+feedId+"'";
       var deleteFeedImagesQuery = "delete from feedImages where feedId='"+feedId+"'";
       model.client.query(listFeedImageQuery,function(err,result){
           //to be executed later
       });
    })(feedArr[i].feedid);
}

现在应该可以了。

【讨论】:

    【解决方案2】:
    for (var i = 0; i < 10; i++) {
      console.log('sync', i);   
      setTimeout(function () {
        console.log('wrong async', i)
      }, 1);
    }
    
    
    for (var i = 0; i < 10; i++) {  
      setTimeout((function (j) {
        console.log('right async', i)
      })(i), 1);
    }
    

    弄清楚,也许你会知道你错在哪里。


    对于您的问题,您可以将异步代码提取为函数,如下所示:

    function deleteImages(feedId) {
        var listFeedImageQuery  = "select imageUrl from feedImages where feedId='"+feedId+"'";
        var deleteFeedImagesQuery = "delete from feedImages where feedId='"+feedId+"'";
        model.client.query(listFeedImageQuery,function(err,result){
            if(result.rows.length > 0){
                for(var j=0; j<result.rows.length; j++){
                    fs.unlink(result.rows[j].imageurl, function(err) {
                        if(err)
                            console.log(err);
                    });
                }
                model.client.query(deleteFeedImagesQuery,function(err,result){
                    if(err)
                        console.log(err)
                    else
                        console.log(feedId +' were removed'); // last feedId only gets removing from database
                });
            }   
        });
    }
    
    for(var i=0; i<feedArr.length; i++){
        var feedId = feedArr[i].feedid;
        deleteImages(feedId);
    }
    

    对于更复杂的问题,如果您不想回调地狱,请尝试asyncbluebird

    【讨论】:

      猜你喜欢
      • 2011-10-17
      • 1970-01-01
      • 2016-11-21
      • 2018-01-19
      • 1970-01-01
      • 1970-01-01
      • 2021-12-19
      • 1970-01-01
      相关资源
      最近更新 更多