2013-07-04 148 views
31

我使用meteor 0.6.4。Meteor.methods返回undefined

Meteor.methods({ 
    random: function(top){ 
    var random = Math.floor((Math.random()*(top+1))); 
    return random; 
    } 
}); 

每當我執行

Meteor.call('random', 10); 

任何想法我怎麼能得到過去,這則返回undefined?

回答

57

這是一個完全正常的行爲:服務器方法調用流星是documented是異步的:

在客戶端,如果不傳遞一個回調,你是不是末節裏,調用將返回未定義,你將無法獲得方法的返回值。

這意味着,當你問一個Meteor.call方法在服務器上遠程執行,調用本地方法是非阻塞,並立即返回undefined。 當方法被調用的服務器上,將異步結果發送給客戶端,所以你應該使用回調格局檢索:

Meteor.call("myMethod", arguments..., function(error, result){ 
    if(error){ 
    console.log(error.reason); 
    return; 
    } 
    // do something with result 
}); 

匿名回調函數將在客戶端上被稱爲儘快服務器方法結果被髮送回客戶端。

流星還有另一個微妙的功能,使我剛剛說的無效:延遲補償和方法存根。 如果服務器方法調用可以在客戶端正確模擬並因此在沒有往返服務器的情況下立即執行,您可以定義稱爲方法存根(或模擬)的東西。

此行爲的一個常見用例是立即在本地(客戶端複製子集)數據庫中插入一些剛剛發佈的用戶內容(例如,在博客文章下的註釋):所有必需的數據和邏輯都可用,它模擬服務器端插入是有意義的。 接下來會發生的事情是,即使服務器尚未確認這些更改,用戶也會在他提交內容後立即看到網頁已更新。 (這是如何在Meteor中實現延遲補償的一個例子)。

當然,服務器最終會在數據庫中插入什麼,這意味着當執行服務器端twin方法時,它的操作將優先並替換插入本地數據庫中的內容。

要定義這種方法存根,您只需在客戶端代碼上定義相同的服務器方法名稱。 如果方法聲明中共享代碼中定義的(都運到客戶端和服務器),你可以測試方法調用實際上是一個模擬通過檢查isSimulation屬性:

Meteor.methods({ 
    myMethod: function(arguments...){ 
     if(this.isSimulation){ 
      // called from the client 
     } 
    } 
}); 

更新26/11/2014: @ steph643評論了我之前回答的最後部分實際上是錯誤的,這裏是一個更正。

請注意,服務器方法調用總是可以使用同步語法來調用,因爲服務器環境提供了足夠的阻塞機制(光纖)。

在客戶端但是,如果從一個方法存根返回的東西,它可以同步只有當你的另一樁內,您可以檢索結果以同步的方式執行,即

Meteor.methods({ 
    intermediateMethod: function(){ 
    return " WORLD"; 
    }, 
    method: function(){ 
    var result = "HELLO"; 
    result += intermediateResult; 
    var intermediateResult = Meteor.call("intermediateMethod"); 
    return result; 
    } 
}); 

考慮到Mongo集合操作(​​insert/update/delete)被實現爲Meteor方法,並且它們的客戶端版本正在實現可以同步執行的有效存根(對minimongo複製的本地數據庫子集的修改),此行爲有點奇怪。

+0

謝謝,不得不讓我的頭,但這幫了很多。 http://www.eventedmind.com/posts/meteor-methods – jaggy

+2

「如果您從方法存根中返回某些內容,它可以在客戶端同步執行,並且可以按照常規方式檢索結果。」這不是真的。無論是否存在存根,客戶端發出的方法調用返回'undefined'。參看該文檔:「在客戶端,如果你沒有傳遞迴調,並且你不在一個存根內(這意味着你不從另一個存根中調用該方法),那麼調用將返回未定義的,並且你將無法獲得該方法的返回值「。這適用於是否將存根連接到該方法。 – steph643

+0

感謝您指出這一點,我也關注流星核心的話題。我在我的答案中引用了文檔,他們明確指出方法存根的客戶端同步執行只能在另一個方法調用中進行,但沒有多大意義,所以我認爲是相反的。 – saimeunt