Ann*_*hou 2 javascript asynchronous firebase firebase-realtime-database
我想将满足特定条件的所有值推送到数组然后返回此数组.这是我的代码
exports.getNearbyPosts = function (myLat, myLng){
var query = firebase.database().ref("posts/").orderByKey();
var listOfItems = [];
query.once("value")
.then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var key = childSnapshot.key;
var childData = childSnapshot.val();
var dist = getDistanceBetweenCoord(childData.lat, childData.lng, myLat, myLng);
if(dist < 10239820938502){
listOfItems.push(childSnapshot);
}
});
});
return listOfItems;
}
Run Code Online (Sandbox Code Playgroud)
但是因为forEach是异步的,而且好像我不能在forEach上使用回调,所以我返回的listOfItems只是一个空数组.我也试过".then",但它只允许我在".then"中做更多的东西,我想把这个数组作为变量返回到代码的其他部分.在执行forEach后如何返回正确的数组?
这不是forEach
async(JavaScript,Node.js:Array.forEach异步吗?),就是这样query.once("value")
.您可以通过各种方式解决此问题.使用回调,承诺或等待/异步.
我建议阅读这个非常丰富的答案,通过更好的例子涵盖更多内容:如何从异步调用返回响应?
这里的想法是提供一个函数,可以在异步工作完成后使用结果调用,但是在我们的工作forEach
完成之后.
exports.getNearbyPosts = function (myLat, myLng, callback){
var query = firebase.database().ref("posts/").orderByKey();
var listOfItems = [];
query.once("value").then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var key = childSnapshot.key;
var childData = childSnapshot.val();
var dist = getDistanceBetweenCoord(childData.lat, childData.lng, myLat, myLng);
if(dist < 10239820938502){
listOfItems.push(childSnapshot);
}
});
callback(listOfItems)
});
}
getNearbyPosts(0, 0, (result) => {
console.log(result);
});
Run Code Online (Sandbox Code Playgroud)
Promise是处理异步代码的另一种方法.我建议在这里阅读它们https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises.它会比我更好地解释它们.
这是使用promises的代码:
exports.getNearbyPosts = function (myLat, myLng){
var query = firebase.database().ref("posts/").orderByKey();
var listOfItems = [];
return new Promise((resolve, reject) => {
query.once("value").then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var key = childSnapshot.key;
var childData = childSnapshot.val();
var dist = getDistanceBetweenCoord(childData.lat, childData.lng, myLat, myLng);
if(dist < 10239820938502){
listOfItems.push(childSnapshot);
}
});
resolve(listOfItems);
});
});
}
getNearbyPosts(0, 0).then(result => {
console.log(result);
});
Run Code Online (Sandbox Code Playgroud)
这实际上可以进一步简化,因为它似乎query.once
返回一个承诺本身.我们可以简单地返回提供给我们的承诺,通过query.once
该承诺将在.then
您的内部功能之后触发一次.我们可以将它们链接在一起.
exports.getNearbyPosts = function (myLat, myLng){
var query = firebase.database().ref("posts/").orderByKey();
var listOfItems = [];
// We return the promise created by query.once
return query.once("value").then((snapshot) => {
// our inital .then will do some data filtering
snapshot.forEach((childSnapshot) => {
var key = childSnapshot.key;
var childData = childSnapshot.val();
var dist = getDistanceBetweenCoord(childData.lat, childData.lng, myLat, myLng);
if(dist < 10239820938502){
listOfItems.push(childSnapshot);
}
});
// We return here to continue the chain. The next .then that picks this up will have this result
return listOfItems;
});
}
// Our last promise resolution in the chain, containing listOfItems
getNearbyPosts(0, 0).then(result => {
console.log(result);
});
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1303 次 |
最近记录: |