如何在Node.js中编写同步函数

时间:2016-03-16 14:12:32

标签: node.js express asynchronous

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

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

到目前为止我做了什么:

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

这里我可以从图像存储文件夹中删除图像,但是我无法从数据库中删除记录。仅删除最后一个Feed记录。其余的feedImage记录都在数据库中。

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

2 个答案:

答案 0 :(得分:1)

当从&#34;标准&#34;切换到回调框架时,这是一个常见问题。之一。

这是它的工作原理,首先它同步运行

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在每个周期被推送到&#34;异步调用堆栈&#34;,因此在执行所有这些查询的那一刻,feedId等于{{1} }

一个简单的解决方法是将其包含在带参数的方法中,然后立即调用它们。

feedArr[feedArr.length-1].feedid

现在应该可以了。

答案 1 :(得分:1)

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

enter image description here

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

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

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