I have a couple of HTML select's (dropdowns) that are populated from a Firebase node called "states" (see image below). Upon choosing a city, the below function fires and should retrieve all meetings occurring in that City. There is a separate "meetings" node and each meeting has various key/value pairs such as street, time, etc.
我有几个HTML select(下拉列表),它们是从名为“states”的Firebase节点填充的(见下图)。选择城市后,以下功能将触发,并应检索该城市中发生的所有会议。有一个单独的“会议”节点,每个会议都有各种键/值对,如街道,时间等。
I (think that I) want to use Promise.all because I want to do a Firebase read (a .once on each meetingID) inside the DataSnapshot.forEach. Below does not work.
我(认为我)想要使用Promise.all,因为我想在DataSnapshot.forEach中执行Firebase读取(每个meetingID上的.once)。以下不起作用。
function loadMeetings(city,state){
//$('#meetingsTable').empty();
var reads = [];
ref.child('states').child(state).child(city).once('value').then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var id = childSnapshot.key();
var dfd = ref.child('meetings').child(id).once('value').then(function(snap) {
// The Promise was fulfilled.
}, function(error) {
// The Promise was rejected.
console.error(error);
});
reads.push( dfd );
});
}, function(error) {
// The Promise was rejected.
console.error(error);
});
Promise.all(reads).then(function(values) {
console.log(values); // [snap, snap, snap]
});
}
{
"geofire" : {
"25dbab9c-8e4e-45ce-a69b-8641b6579560" : {
".priority" : "9q5cc9ye4w",
"g" : "9q5cc9ye4w",
"l" : [ 34.0677809, -118.4016105 ]
},
"3d2c7948-16e5-466c-b0d8-0a9e24ed7529" : {
".priority" : "7zzzzzzzzz",
"g" : "7zzzzzzzzz",
"l" : [ 0, 0 ]
},
"3fc846d4-7e55-4134-a0f5-9393aaf02269" : {
".priority" : "dhyy1zhnu1",
"g" : "dhyy1zhnu1",
"l" : [ 27.8130538, -80.42524100000003 ]
},
"5952bd9f-8438-44b0-addb-a5b806dab5da" : {
".priority" : "9vw1zzv421",
"g" : "9vw1zzv421",
"l" : [ 31.288082, -92.46505450000001 ]
},
"7001c8a7-c4f0-44ba-a4fc-2dba32097cc6" : {
".priority" : "9vqe68qs06",
"g" : "9vqe68qs06",
"l" : [ 30.1046126, -91.99056969999998 ]
},
"ecb350d6-6664-4f95-9c1c-2fd1d2f11a40" : {
".priority" : "9vrk9tstc9",
"g" : "9vrk9tstc9",
"l" : [ 30.353474, -90.98251599999998 ]
}
},
"markup" : {
"addMeeting" : "New Meeting
",
"admin" : " Welcome.
Running Scripts...
Running Scripts...
Running Scripts...
Running Scripts...
Running Scripts...
",
"adminWelcome" : "This is the admin welcome pane
",
"login" : "
Log In
",
"manageMeeting" : ""
},
"meetings" : {
"25dbab9c-8e4e-45ce-a69b-8641b6579560" : {
"author" : "Ron Royston",
"beginner" : true,
"bigBook" : true,
"childcare" : false,
"city" : "los angeles",
"day" : "sunday",
"discussion" : false,
"hour" : "4",
"key" : "25dbab9c-8e4e-45ce-a69b-8641b6579560",
"latitude" : 34.0677809,
"layer" : "",
"longitude" : -118.4016105,
"meditation" : false,
"meetingOpen" : false,
"min" : ":00",
"name" : "highrise",
"onlyMen" : false,
"onlyWomen" : true,
"spanish" : true,
"speaker" : false,
"state" : "california",
"step" : false,
"street" : "111 rodeo",
"timeframe" : "pm",
"timestamp" : 1457470568863,
"tradition" : true,
"type" : "",
"user" : "facebook:196986260658947",
"zip" : "90210"
},
"3d2c7948-16e5-466c-b0d8-0a9e24ed7529" : {
"author" : "Ron Royston",
"beginner" : false,
"bigBook" : false,
"childcare" : false,
"city" : "baton rouge",
"day" : "sunday",
"discussion" : false,
"hour" : "1",
"key" : "3d2c7948-16e5-466c-b0d8-0a9e24ed7529",
"latitude" : 0,
"layer" : "",
"longitude" : 0,
"meditation" : false,
"meetingOpen" : false,
"min" : ":00",
"name" : "asdf",
"onlyMen" : false,
"onlyWomen" : false,
"spanish" : false,
"speaker" : false,
"state" : "louisiana",
"step" : false,
"street" : "234 kjhkj",
"timeframe" : "am",
"timestamp" : 1457470215505,
"tradition" : false,
"type" : "",
"user" : "facebook:196986260658947",
"zip" : "70817"
},
"3fc846d4-7e55-4134-a0f5-9393aaf02269" : {
"author" : "Ron Royston",
"beginner" : false,
"bigBook" : true,
"childcare" : true,
"city" : "miami",
"day" : "sunday",
"discussion" : true,
"hour" : "1",
"key" : "3fc846d4-7e55-4134-a0f5-9393aaf02269",
"latitude" : 27.8130538,
"layer" : "",
"longitude" : -80.42524100000003,
"meditation" : false,
"meetingOpen" : false,
"min" : ":00",
"name" : "beach",
"onlyMen" : false,
"onlyWomen" : false,
"spanish" : true,
"speaker" : false,
"state" : "florida",
"step" : false,
"street" : "120 a1a",
"timeframe" : "am",
"timestamp" : 1457470499310,
"tradition" : false,
"type" : "",
"user" : "facebook:196986260658947",
"zip" : "33101"
},
"5952bd9f-8438-44b0-addb-a5b806dab5da" : {
"author" : "Ron Royston",
"beginner" : true,
"bigBook" : false,
"childcare" : false,
"city" : "alexandria",
"day" : "sunday",
"discussion" : false,
"hour" : "1",
"key" : "5952bd9f-8438-44b0-addb-a5b806dab5da",
"latitude" : 31.288082,
"layer" : "",
"longitude" : -92.46505450000001,
"meditation" : false,
"meetingOpen" : false,
"min" : ":00",
"name" : "howdy",
"onlyMen" : false,
"onlyWomen" : false,
"spanish" : false,
"speaker" : false,
"state" : "louisiana",
"step" : false,
"street" : "5676 city park",
"timeframe" : "am",
"timestamp" : 1457470284850,
"tradition" : true,
"type" : "",
"user" : "facebook:196986260658947",
"zip" : "71301"
},
"7001c8a7-c4f0-44ba-a4fc-2dba32097cc6" : {
"author" : "Ron Royston",
"beginner" : false,
"bigBook" : false,
"childcare" : false,
"city" : "lafayette",
"day" : "sunday",
"discussion" : false,
"hour" : "1",
"key" : "7001c8a7-c4f0-44ba-a4fc-2dba32097cc6",
"latitude" : 30.1046126,
"layer" : "",
"longitude" : -91.99056969999998,
"meditation" : false,
"meetingOpen" : false,
"min" : ":00",
"name" : "test3",
"onlyMen" : false,
"onlyWomen" : false,
"spanish" : false,
"speaker" : false,
"state" : "louisiana",
"step" : false,
"street" : "234 kjhkj",
"timeframe" : "am",
"timestamp" : 1457470252872,
"tradition" : false,
"type" : "",
"user" : "facebook:196986260658947",
"zip" : "70500"
},
"ecb350d6-6664-4f95-9c1c-2fd1d2f11a40" : {
"author" : "Ron Royston",
"beginner" : false,
"bigBook" : false,
"childcare" : false,
"city" : "baton rouge",
"day" : "sunday",
"discussion" : false,
"hour" : "5",
"key" : "ecb350d6-6664-4f95-9c1c-2fd1d2f11a40",
"latitude" : 30.353474,
"layer" : "",
"longitude" : -90.98251599999998,
"meditation" : true,
"meetingOpen" : false,
"min" : ":00",
"name" : "test1",
"onlyMen" : false,
"onlyWomen" : false,
"spanish" : false,
"speaker" : true,
"state" : "louisiana",
"step" : false,
"street" : "18432 lake iris",
"timeframe" : "pm",
"timestamp" : 1457470192281,
"tradition" : false,
"type" : "",
"user" : "facebook:196986260658947",
"zip" : "70817"
}
},
"states" : {
"california " : {
"los angeles" : {
"25dbab9c-8e4e-45ce-a69b-8641b6579560" : true
}
},
"florida " : {
"miami" : {
"3fc846d4-7e55-4134-a0f5-9393aaf02269" : true
}
},
"louisiana " : {
"alexandria" : {
"5952bd9f-8438-44b0-addb-a5b806dab5da" : true
},
"baton rouge" : {
"3d2c7948-16e5-466c-b0d8-0a9e24ed7529" : true,
"ecb350d6-6664-4f95-9c1c-2fd1d2f11a40" : true
},
"lafayette" : {
"7001c8a7-c4f0-44ba-a4fc-2dba32097cc6" : true
}
}
}
}
17
You have to execute the Promise.all
after you filled the array with promises, i.e. inside the then
callback:
在用promises填充数组后,你必须执行Promise.all,即在then回调中:
function loadMeetings(city,state) {
//$('#meetingsTable').empty();
return ref.child('states').child(state).child(city).once('value').then(function(snapshot) {
var reads = [];
// ^^^^^^^^^^^^^^
snapshot.forEach(function(childSnapshot) {
var id = childSnapshot.key();
var promise = ref.child('meetings').child(id).once('value').then(function(snap) {
// The Promise was fulfilled.
}, function(error) {
// The Promise was rejected.
console.error(error);
});
reads.push(promise);
});
return Promise.all(reads);
// ^^^^^^^^^^^^^^^^^
}, function(error) {
// The Promise was rejected.
console.error(error);
}).then(function(values) {
console.log(values); // [snap, snap, snap]
});
}
Btw, if snapshot
is an array you can simplify your code by using map
instead of forEach
.
顺便说一下,如果快照是一个数组,你可以使用map而不是forEach来简化你的代码。