2017-04-12 47 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