2015-04-07 69 views
1

我有meteor.js如何使onBeforeAction調用等待,直到內部函數調用完成meteor.js?

Router.onBeforeAction(function() { 
    var self; 

    self = this; 

    authToken = Session.get('authToken'); 

    if (!authToken) { 
     this.redirect('login'); 
     this.next(); 
    } else { 
     Meteor.call('validateAuthToken', authToken, function (error, result)) { 
      if (result) { 
       self.next(); 
      } else { 
       self.redirect('login'); 
       self.next(); 
      } 
     } 
    } 
}); 

我需要通過調用服務器呼叫,以驗證存儲在會話認證令牌同步onBeforeAction方法。但是當我執行它時,這個方法總是拋出一個異常。我發現原因是因爲onBeforeAction調用在validateAuthToken調用返回之前終止。因此self.next()不會採取行動。所以我想知道我能做些什麼來阻止onBeforeAction調用停止,直到validateAuthToken返回驗證結果,然後繼續?


我已經嘗試通過等待一個會話變量不同的實現,但似乎就緒狀態永遠不會設置爲true

Router.onBeforeAction(function() { 
    var authToken; 

    authToken = Session.get('authToken'); 

    if (!authToken) { 
     this.redirect('login'); 
     this.next(); 
    } else { 
     Meteor.call('validateAuthToken', authToken, function (error, result) { 
      if (!error) { 
       Session.set("tokenValidated", result); 
      } 
     }); 

     this.wait(Meteor.subscribe('token', Session.get('tokenValidated'))); 
     if (this.ready()) { 
      if (!Session.get("tokenValidated")) { 
       this.redirect('login'); 
       this.next(); 
      } else { 
       this.next(); 
      } 
     } 
    } 

}); 

回答

1

編輯:這個問題的工作後,一點點我想出了一個工作的例子(沒有無限循環)。您可以使用下面的代碼:

Util = {}; 

// We need to store the dep, ready flag, and data for each call 
Util.d_waitOns = {}; 

// This function returns a handle with a reactive ready function, which 
// is what waitOn expects. waitOn will complete when the reactive function 
// returns true. 
Util.waitOnServer = function(name) { 
    // This prevents the waitOnServer call from being called multiple times 
    // and the resulting infinite loop. 
    if (this.d_waitOns[name] !== undefined && 
     this.d_waitOns[name].ready === true) { 
    return; 
    } 
    else { 
    this.d_waitOns[name] = {}; 
    } 
    var self = this; 
    // We need to store the dependency and the ready flag. 
    this.d_waitOns[name].dep = new Deps.Dependency(); 
    this.d_waitOns[name].ready = false; 

    // Perform the actual async call. 
    Meteor.call(name, function(err, or) { 
    // The call has complete, so set the ready flag, notify the reactive 
    // function that we are ready, and store the data. 
    self.d_waitOns[name].ready = true; 
    self.d_waitOns[name].dep.changed(); 
    self.d_waitOns[name].data = (err || or); 
    }); 

    // The reactive handle that we are returning. 
    var handle = { 
    ready: function() { 
     self.d_waitOns[name].dep.depend(); 
     return self.d_waitOns[name].ready; 
    } 
    }; 
    return handle; 
} 

// Retrieve the data that we stored in the async callback. 
Util.getResponse = function(name) { 
    return this.d_waitOns[name].data; 
} 

這是從waitOn稱爲像這樣:

Router.route("/test", { 
    name: "test", 
    action: function() { 
    console.log("The data is ", Util.getResponse("testWaitOn")); 
    }, 
    waitOn: function() { 
    return Util.waitOnServer("testWaitOn"); 
    } 
}) 

我在深入的解釋,你可以在這裏找到寫了一篇博客文章以更

http://www.curtismlarson.com/blog/2015/05/04/meteor-ironrouter-waitOn-server/

+0

我試過這個實現,但似乎由於某種原因我正在運行到一個無限循環 –

+0

我可以看到,如果你在登錄頁面,這可能會遇到無限循環。我在'Router.onBeforeAction'上添加了一個'except'。 – Curtis

+0

儘管如此,它仍然是一個無限循環,來自任何路線 –

0

您也可以使用此代碼段從https://github.com/iron-meteor/iron-router/issues/426

Ready = new Blaze.ReactiveVar(false); 
Router.route('feed',{ 
    waitOn: function() { 
    Meteor.call('getInstagramUserFeed', function(error, result) { 
     if(!error) Ready.set(result) 
    }); 
    return [ 
     function() { return Ready.get(); } 
    ]; 
    }, 
    action: function() { 
    if (this.ready()) this.render('feed') 
    else this.render('LoadingMany'); 
    } 
}); 
相關問題