2016-02-01 125 views
0

我一直在將一個值綁定到下一個Promise時遇到問題。看下面的代碼,它會更好地解釋情況。Promise.then綁定問題

'use strict'; 

function FindEvent(eventId) { 
    console.log('Event:', eventId); 
    return Promise.resolve({title: 'MyEvent'}); 
} 

function FindUser(userId) { 
    console.log('User:', userId); 
    return Promise.resolve({username: 'MyUser'}); 
} 

function MyServiceProblem(payload) { 
    payload.userId = 'blah'; 
    return FindEvent(payload.eventId) 
     .then((event) => { 
      payload.userId = 'test'; 
      // setting a breakpoint here shows 
      // that the value to payload.userId has been 
      // assigned, i.e. 'test' 

      return Promise.resolve(payload); 
     }) 
     .then(FindUser.bind(this, payload.userId)); 
     // But new value doesn't reaches inside FindUser 
} 

MyServiceProblem({ // userId is 'blah', why not 'test' 
    eventId: '456' 
}); 

function MyServiceWorks(payload) { 
    payload.userId = 'blah'; 
    return new Promise((resolve) => { 
     payload.userId = 'test'; 

     return resolve(payload); 
    }) 
     .then(FindUser.bind(this, payload.userId)); 
     // From here, the 'test' value reaches FindUser 
} 

MyServiceWorks({ // userId is 'test' 
    eventId: '456' 
}); 

問題是,爲什麼它綁定的值在兩種情況下都不相同。兩者是完全一樣的,除了這一個是首先解決承諾的一部分,然後分配一個值爲payload.userId

+0

在MyServiceWorks你正在返回的承諾,但在findUser要返回Promise.resolve – Avinash

+0

那麼它與在未來的承諾結合的值呢? –

+0

我想你可能想嘗試'返回新的Promise.resolve(有效載荷);'在'MyServiceProblem'中。 '新'很重要。 – Ali

回答

2

讓我們分解一下你的代碼。你有

function MyServiceProblem(payload) { 
    payload.userId = 'blah'; 
    return FindEvent(payload.eventId) 
     .then((event) => { 
      payload.userId = 'test'; 

      return Promise.resolve(payload); 
     }) 
     .then(FindUser.bind(this, payload.userId)); 
} 

的問題是,你的.bind將您的回調之前運行。此代碼也可以寫成

function MyServiceProblem(payload) { 
    payload.userId = 'blah'; 

    var firstThenCallback = (event) => { 
     payload.userId = 'test'; 
     return Promise.resolve(payload); 
    }; 
    var secondThenCallback = FindUser.bind(this, payload.userId); 

    return FindEvent(payload.eventId) 
     .then(firstThenCallback) 
     .then(secondThenCallback); 
} 

的​​對象跨所有共享,但payload.userId傳遞到.bind之前firstThenCallback有機會來執行。

相反,使用.bind並立即傳遞值,似乎最簡單的解決方案是使用匿名函數,因此userId值只能在稍後讀取。

function MyServiceProblem(payload) { 
    payload.userId = 'blah'; 
    return FindEvent(payload.eventId) 
     .then((event) => { 
      payload.userId = 'test'; 

      return Promise.resolve(payload); 
     }) 
     .then(() => FindUser(payload.userId)); 
} 

你不明白爲什麼你寫了這樣一個循環的承諾代碼,但我認爲這是一個微調的例子?你爲什麼用​​來解決,而不是僅僅在該函數中調用FindUser,例如,

function MyServiceProblem(payload) { 
    payload.userId = 'blah'; 
    return FindEvent(payload.eventId) 
     .then((event) => { 
      payload.userId = 'test'; 

      return FindUser(payload.userId); 
     }); 
} 
+0

感謝您的解釋! 我寫了這樣的代碼,因爲當我摺疊所有的'then()'時,它變得更具可讀性。它讀起來像這樣:FindEvent()。then(FindUser())。then(doOtherThing())''。我顯然沒有從'findEvent()'獲取'userId'。 –