如何使用包含mongoose函数的方法与控制流框架(例如Async或Step)

时间:2012-07-05 07:56:49

标签: javascript node.js mongoose control-flow

我正在努力解决如何以串行方式调用异步函数的问题。特别是,包含对数据库的mongoose调用的函数。我有一个类定义,它包括两个方法:( MovieFile.exists)检查数据库中是否存在某个记录; (MovieFile.save)将记录保存在数据库中。理想情况下,我希望能够在确认它是否存在于数据库(MovieFile.exists())之后保存记录(MovieFile.save())。

理想情况下,我想做这样的事情:

// Create instance of MovieFile object.  
var movieFile = new MovieFile(mongoose);
if (movieFile.exists() === false) {
  movieFile.save();
}

不幸的是,mongoose的异步特性使得这种情况无法实现。我一直在玩StepAsync控制流框架。不幸的是,在这种情况下,我无法理解如何使用这样的框架。如果有人能告诉我如何将上述代码放入Step或Async,我将不胜感激。我认为问题在于异步mongoose调用本身嵌入在一个方法中(参见:MovieFile.exists和MovieFile.save)。我意识到在这个例子中使用这样的框架可能有些过分,但我试图将其作为一种学习练习。

function MovieFile(mongoose) {
  var Movie = mongoose.model('Movie');

  this.exists = function() {
    // Confirm necessary object variables have been set.
    if (typeof this.originalFileName === 'undefined') {
      throw error = new Error('Variable originalFilename has not been set for MovieFile.');
    }
    if (typeof this.fileSize !== 'number') {
      throw error = new Error('Variable originalFilename has not been set for MovieFile.');
    }
    // Check database for existing record.
    Movie
      .find({ originalFileName: this.originalFileName, size: this.fileSize })
      .exec(function(error, results) {
        if (error) {
          throw error;
        }
        else if (results.length === 0) {
          return false;
        }
        else if (results.length === 1) {
          return true;
        }
        else {
          throw error = new Error('More than one record for this movie record exists.');
        }
      });
  };

  this.save = function() {
    // save movie to database.
    var values = {
      name: this.getName(),
      machineFileName: this.getMachineFileName(),
      originalFileName: this.getName(),
      size: this.getFileSize(),
    };
    var movie = new Movie(values);
    movie.save(function(error, data) {
      if (error) {
        console.log(error);
      }
      else {
        console.log('Movie saved.');
      }
    });
  };
};

1 个答案:

答案 0 :(得分:2)

您必须将回调传递给exists函数,它将返回布尔值truefalse

例如:

this.exists = function(callback) {

   // your code

   callback(true);

}); 

然后:

movieFile.exists(function(exists) {

     if (!exists) boomovieFile.save();

});

正如你所说,这是由于异步mongoose调用。因此,您必须通过回调替换return语句。

我从未使用过Step或Async控制流框架。但我认为,您不需要依赖这些模块来处理这种简单的情况。在我看来,只有当你需要处理很多回调时才应该考虑使用这些模块。

修改

由于我是控制流程框架的新手,我发现this article很好地描述了这个概念,并展示了如何构建自己的概念。这对学习目的很有帮助。

This article将为您提供有关如何使用异步模块管理队列的示例。

This post列出了一些其他控制流模块,只有几个例子。 第一个答案还展示了如何通过解耦小函数来避免嵌套回调。这就是我个人管理我的应用程序的方式,在我的情况下效果非常好。

但我很想知道有关控制流技术的更多信息,所以如果你找到了很好的资源,请告诉我。