2016-01-15 45 views
0

我在我的node.js文件中有以下代碼;承諾完成後調用另一個原型方法

GameHelperAuth.prototype.GetUserViaApi = Promise.method(function (authCookie, callback) { 
// get user from API 
}); 

GameHelperAuth.prototype.GetObjectFromCache = Promise.method(function (authCookie, callback) { 
// get user from Cache 
}); 

GameHelperAuth.prototype.GetUser = function (authCookie, callback) {  
    // check cache  
    this.GetObjectFromCache() 
     .then(function (result) { 
      if (result) { 
       return callback(null, result); 
      } 
      else { 
      // not found in cache, get it from API 
      // **NOT WORKING HERE - undefined error** 
       this.GetUserViaApi(authCookie) 
        .then(function (apiResult) { 
         return callback(null, apiResult); 
        }).catch(function (err) { 
         throw err; 
        }); 
      } 
     }) 
     .catch(function (err) { 
      throw err; 
     }); 

一旦承諾完成,我想從另一個實例方法訪問我的實例方法。但它看起來失去了它的上下文,無法再找到功能。 (請看我在哪裏打電話給GetUserViaApi方法)

有沒有什麼辦法讓我達到該方法,而不創建我的課程的新實例?

+0

不要採取回調參數 - 返回承諾。如果您必須使用回調,請使用nodeify進行正確的翻譯 –

+0

您是否使用'var self'或箭頭函數解決方案? – Alnitak

+0

現在就像我用自己一樣容易實現。將重構爲下一版本的箭頭。 –

回答

3

據我所看到的,在這裏最簡單的解決方法是隻是聲明var self = this.GetUser()第一線,然後用self代替this.then回調裏面。

另外,如果你使用節點4+與ES6的兼容性,使用「箭頭功能」作爲外.then回調繼承詞法this而不是上下文this

return this.GetObjectFromCache() 
    .then((result) => { 
     if (result) { 
      return callback(null, result); 
     } else { 
      // not found in cache, get it from API 
      return this.GetUserViaApi(authCookie) 
       .then(function (apiResult) { 
        return callback(null, apiResult); 
       }).catch(function (err) { 
        throw err; 
       }); 
     } 
    }) 
    .catch(function (err) { 
     throw err; 
    }); 

注意:注意加的第一行和else子句中,必須確保函數和該分支都正確地返回承諾。

FWIW,我還以爲你可以通過一個鏈接.then消除了return callback(...)再三呼籲大幅重構這個:

GameHelperAuth.prototype.GetUser = function (authCookie, callback) { 
    return this.GetObjectFromCache() 
     .then(result => result || this.GetUserViaApi(authCookie)) 
     .then(result => callback(null, result)); 
} 

我已經去除了這兩種.catch塊 - 做.catch(function(err) { throw err })是一個無操作 - AIUI throw會使呼叫者以自己的.catch塊結束,因此您可能還是會拒絕整個承諾。

+0

值得一提的是'.catch(err => {throw err})'是沒有操作的。 –

+0

@BenjaminGruenbaum是的,TBH我不確定混合'.catch'和'throw'的語義 - 在我自己的代碼中,我可能會讓這個泡泡在函數內部沒有'.catch'。除了那個之外,這個鏈式版本是如何看待你的? – Alnitak

+0

@BenjaminGruenbaum回覆:您的編輯 - 我知道單個參數箭頭函數不需要括號,但我更願意將它們與零或2+參數語法保持一致。 – Alnitak

相關問題