2012-07-05 27 views
0

我正在爲如何以串行方式調用異步函數而苦苦掙扎。特別是將函數調用數據庫的函數。我有一個包含兩個方法的類定義:(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.'); 
     } 
    }); 
    }; 
}; 

回答

2

你有一個回調傳遞給您的exists功能,至極將返回布爾truefalse

例:

this.exists = function(callback) { 

    // your code 

    callback(true); 

}); 

然後:

movieFile.exists(function(exists) { 

    if (!exists) boomovieFile.save(); 

}); 

正如你所說,這是由於異步調用貓鼬。所以,你將不得不通過回調替換你的return聲明。

我從來沒有用過Step或Async控制流框架。但我認爲,您不需要依賴這些模塊來處理這種簡單的情況。在我看來,當你需要處理大量的回調時,你應該只考慮使用這些模塊。

編輯

由於我是新來控制流動框架,我發現this article這很好地描述了這一概念,並展示瞭如何建立你自己的。這對於學習目的來說很好。

This article將舉例說明如何使用異步模塊管理隊列。

This post列舉了一些其他的控制流模塊,僅舉幾個例子。 第一個答案還顯示瞭如何通過在小函數上解耦來避免嵌套回調。這就是我personnaly管理我的應用程序的方式,在我的情況下效果很好。

但是我很想知道更多關於控制流技術的知識,所以讓我知道你是否找到了很好的資源。

+0

感謝您的快速回復。實際上,您提出的方法是我已經實施的解決方案,用於解決這個特定問題。不過,我試圖將此作爲學習練習,使用控制流框架。叫我迂腐,但我想知道如何使用異步來實現這一點。我試圖理解這種框架在這種情況下是如何工作的,以便我將來可以使用它。 – Benjen

+0

因爲我現在無法嘗試這些模塊,所以我用一些鏈接更新了我的文章。 –

+0

我終於搞定了。我忽略了一個非常重要,非常明顯的事物;該功能本質上是異步的。由於MovieFile.exists()不會將回調作爲參數,因此它絕不會用於像Async這樣的框架。所以實際上我最初的懷疑是正確的,這個問題是由於在同步函數中嵌入了一個異步函數,現在這個函數顯而易見。你的鏈接可以幫助我解決所有問題。我覺得非常開明。謝謝。 – Benjen