2017-02-11 6 views
2

私はredux saga APIを持っています。ここでfirebaseに接続してデータのレコードを読み込みます。firebaseでのyieldを呼び出す方法read API

var roomRef = firebase.database().ref('/Users/' + userid + '/rooms') 
    var rooms = [] 
    roomRef.once('value', function (snap) { 
    var roomkeys = snap.val() 
    for (var roomkey in roomkeys) { 
     firebase.database().ref('/Rooms/' + roomkey).once('value', function (item) { 
     rooms.push(item.val()) 
     }) 
    } 
    console.log(rooms) 
    --> put({type: 'LOAD_ROOMS', payload: { rooms: rooms}}) 
    }) 

私のputはコールバック関数の内部にあるのでyieldキーワードは使用できません。新しい値「部屋」を使用してレデューサーの状態を変更するイベントをディスパッチするには

答えて

2

これを回避する方法は、コールバックを約束に変換することです。 redux-sagaはcall effectに渡す約束を解決する方法を知っています。しかし、呼び出しは機能であり、約束ではありません。ドキュメントが

の場合、ミドルウェアはプロミスが解決されるまでジェネレータを中断します。その場合、ジェネレータは解決された値でレジュームされます。プロミスが却下されるまでは、ジェネレータの内部でエラーが発生します。

var roomRef = firebase.database().ref('/Users/' + userid + '/rooms') 
var rooms = yield call(function() { 
    return new Promise(function(resolve, reject) { 
    roomRef.once('value', function (snap) { 
     var rooms = [] 
     var roomkeys = snap.val() 
     for (var roomkey in roomkeys) { 
     firebase.database().ref('/Rooms/' + roomkey).once('value', function (item) { 
      rooms.push(item.val()) 
     }) 
     } 
     resolve(rooms) 
    }) 
    }) 
}) 
yield put({type: 'LOAD_ROOMS', payload: { rooms: rooms}}) 
+0

チャームのように働いた!ありがとう! – Ricky

+3

この場合、firebaseの 'once'メソッドはすでにPromiseを返すので、Promiseを自分でインスタンス化する必要はありません。 'function getRooms(userId){firebase.database()。ref( 'users /' + userId + '/ rooms')を一回( 'value')返します。 val())} 'を呼び出すと、const rooms = yield call(getRooms、userId)' – VonD

関連する問題