2012-11-02 112 views
8

如何讓客戶端的method.call等待異步函數完成?目前它到達函數的末尾並返回undefined。同步MeteorJS異步代碼Meteor.methods函數

Client.js

Meteor.call('openSession', sid, function(err, res) { 
    // Return undefined undefined 
    console.log(err, res); 
}); 

Server.js

Meteor.methods({ 
    openSession: function(session_id) { 
     util.post('OpenSession', {session: session_id, reset: false }, function(err, res){ 
      // return value here with callback? 
      session_key = res; 
     }); 
    } 
}); 
+0

我認爲不可能在客戶端的流星方法內執行異步任務。在使用光纖的服務器可能是一個選項。 – Andreas

回答

6

最近流星的版本都提供了無證Meteor._wrapAsync功能,開啓功能與標準(err, res)回調轉換爲同步函數,這意味着當前的光纖收益直到回調返回,然後使用Meteor.bindEnviro以確保您保留當前Meteor環境變量(如Meteor.userId())

一個簡單的用途是爲以下幾點:

asyncFunc = function(arg1, arg2, callback) { 
    // callback has the form function (err, res) {} 

}; 

Meteor.methods({ 
    "callFunc": function() { 
    syncFunc = Meteor._wrapAsync(asyncFunc); 

    res = syncFunc("foo", "bar"); // Errors will be thrown  
    } 
}); 

你也可能需要使用function#bind確保asyncFunc被包裹之前調用正確的上下文。 欲瞭解更多信息,請參閱:https://www.eventedmind.com/tracks/feed-archive/meteor-meteor-wrapasync

6

我能找到答案this gist。爲了在method.call中運行異步代碼,你需要使用Futures來強制你的函數等待。

var fut = new Future(); 
    asyncfunc(data, function(err, res){ 
     fut.ret(res); 
    }); 
    return fut.wait(); 
+0

我打算提出未來/承諾,但沒有意識到它是內置於流星。在各地都很有用。 – Dror

+1

你是直的G.這是一些拍攝呼叫者級別代碼在這裏 – OneChillDude

+1

期貨不再是Meteor核心的一部分,所以這不再起作用。 – iiz

0

更新:對不起,我應該更仔細地閱讀這個問題。看起來這個問題也被問及並回答了here

除期貨以外,另一種需要考慮的模式可能是使用從異步調用返回的數據更新另一個模型,然後訂閱該模型的更改。


meteor.call documentation它看起來像你的回調函數應該包含你的openSession函數的輸出的結果的說法(err, res)。但是你沒有從openSession函數返回任何值,所以返回值是未定義的。

您可以測試:

客戶:

Meteor.call('foo', function(err, res) { 
    console.log(res); // undefined 
}); 

Meteor.call('bar', function(err, res) { 
    console.log(res); // 'bar' 
}); 

服務器:

Meteor.methods({ 
    foo: function() { 
    var foo = 'foo'; 
    }, 
    bar: function() { 
    var bar = 'bar'; 
    return bar; 
    } 
});