2017-04-12 60 views
0

我正在使用基於Firebase的反應制作網站。最近,我遇到了一些關於獲取存儲URL的問題。 以下是我的代碼。如何在React和Firebase中承諾返回值?

(state, action) => { 
    const snapshot = action.payload; 
    const list = []; 

    snapshot.forEach((child) => { 
    list.push({ 
     key: child.key, 
     user_bg_url: child.val().user_bg_url, 
     user_hp: child.val().user_hp, 
     user_id: child.val().user_id, 
     user_img_url: child.val().user_img_url, 
     user_login_yn: child.val().user_login_yn, 
     user_msg_block: child.val().user_msg_block, 
     user_token: child.val().user_token, 
    }); 
    }); 

    list.forEach(async (user) => { 
    await storage.getUserImage(user.user_img_url).then((url) => { 
     user.user_img_url = url; 
    }); 
    }) 

    return state.setIn(['users', 'list'], list); 
} 

getUserImage: (gs_url) => { 
    return storage.refFromURL(gs_url).getDownloadURL(); 
}, 

我想 'list.forEach' 的工作後返回值。但它只是在完成'list.forEach'之前返回空數組。

+0

改爲使用.map,從而創建一個承諾數組,然後等待。 –

回答

1

forEach完成之前,您確定return已被調用,因此您需要返回承諾。使用Promise.all()map可以在這裏工作。

return Promise.all(list.map(async (user) => { 
    await storage.getUserImage(user.user_img_url).then((url) => { 
    user.user_img_url = url; 
    }); 
})).then(() => { 
    return state.setIn(['users', 'list'], list); 
}); 

this answer的啓發。

+0

答謝謝,傑夫。但是這個答案沒有回報我想要的價值。 – OH3VCI

+0

因爲我爲了方便而使用了具體的功能狀態()。所以,如果返回值是函數,它不會被賦予特定的函數。所以原始代碼只返回狀態。 – OH3VCI

+0

看起來像你在這裏使用REDX。通常,類似你的函數的reducers不會做任何異步操作,因爲它們需要返回狀態對象。查看使用異步操作(http://redux.js.org/docs/advanced/AsyncActions.html)來執行異步操作,並且只有在獲得所需結果時才調用reducer。 – Jeff