0

我在如何以串行方式调用异步函数方面有点挣扎。特别是,将 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();
}

不幸的是,猫鼬的异步特性使得这不可能。我一直在玩StepAsync控制流框架。不幸的是,在这种情况下,我无法理解如何使用这些框架。如果有人能告诉我如何将上述代码放入 Step 或 Async 中,我将不胜感激。我认为问题在于异步猫鼬调用本身嵌入在一个方法中(参见: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.');
      }
    });
  };
};
4

1 回答 1

2

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

例子:

this.exists = function(callback) {

   // your code

   callback(true);

}); 

然后 :

movieFile.exists(function(exists) {

     if (!exists) boomovieFile.save();

});

正如你所说,这是由于异步猫鼬调用。因此,您将不得不return用回调替换您的语句。

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

编辑

由于我是控制流框架的新手,我发现这篇文章很好地描述了这个概念并展示了如何构建你自己的。这对学习目的非常有用。

本文将为您提供一个有关如何使用 async 模块管理队列的示例。

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

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

于 2012-07-05T08:04:19.497 回答