NodeJS Promise 和异步问题 (Firebase)
NodeJS Promise and Async Problems (Firebase)
问题出在 promise 和异步函数上。 "All moved" 应该在 async.each 中的所有内容完成后记录。但是什么都没有记录。
这是我的导出函数:
var courier_id = data.ref.parent.key;
return admin.database().ref("firewall_queue/"+courier_id+"/orders").once('value',function(orders){
//console.log(Object.keys(orders.val()));
async.each(Object.keys(orders.val()), function (order, callback) {
if(order != "none") {
return moveToWaitingFromFirewall(order).then(callback())
}
},
function (err) {
console.log("All moved");
return admin.database().ref("/firewall_queue/"+courier_id+"/orders/").remove().then(()=>{
return pushToPending(courier_id,data.ref.key);
})
});
})
这是我的 moveToWaitingFromFirewall 函数:
function moveToWaitingFromFirewall(order_id){
var order = {};
order.id = order_id;
var promises = [];
promises.push(new Promise((resolve) => {
admin.database().ref("orders/"+order_id+"/zone").once('value').then(function(zone){
order.zone = zone.val();
resolve();
})
}))
promises.push(new Promise((resolve) => {
admin.database().ref("orders/"+order_id+"/time_order_placed").once('value').then(function(time_order_placed){
order.time = time_order_placed.val();
resolve();
})
}))
//grab zone and time first
return Promise.all(promises).then(()=>{
return admin.database().ref(order.zone+"/wait_order_queue/"+order.id).set(order.time);
})
}
JSON Firebase
"c98" : {
"orders" : {
"0333" : 123123,
"0345" : 12,
"0911" : 123,
"none" : "none"
}
稍微研究一下,也许可以应用到您当前的代码中。
想象一下 admin.database().ref("orders/"+order_id+"/time_order_placed").once('value')
就像 delay(time)
// let delay = time => new Promise(res=>setTimeout(res,time));
let delay = function(time){
return new Promise(function(resolve,reject){
setTimeout(function(){
resolve();
},time);
});
}
let myPromise = function(order){
return Promise.all([
delay(500),
delay(500),
delay(1000).then(function(){
console.log('Order complete: ',order);
return; // returns undefined, so cb doesn't pass anything to cb(err), but use ()=>cb() to avoid this anyways.
})
]);
}
let orders = [1,2,3];
async.each(orders,function(order,cb){
myPromise(order)
.then(()=>cb())
.catch(err=>cb(err));
},function(err,data){
if(err){
console.log('Err',err);
}else{
console.log('all Finished');
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/async/2.6.0/async.js"></script>
问题出在 promise 和异步函数上。 "All moved" 应该在 async.each 中的所有内容完成后记录。但是什么都没有记录。
这是我的导出函数:
var courier_id = data.ref.parent.key;
return admin.database().ref("firewall_queue/"+courier_id+"/orders").once('value',function(orders){
//console.log(Object.keys(orders.val()));
async.each(Object.keys(orders.val()), function (order, callback) {
if(order != "none") {
return moveToWaitingFromFirewall(order).then(callback())
}
},
function (err) {
console.log("All moved");
return admin.database().ref("/firewall_queue/"+courier_id+"/orders/").remove().then(()=>{
return pushToPending(courier_id,data.ref.key);
})
});
})
这是我的 moveToWaitingFromFirewall 函数:
function moveToWaitingFromFirewall(order_id){
var order = {};
order.id = order_id;
var promises = [];
promises.push(new Promise((resolve) => {
admin.database().ref("orders/"+order_id+"/zone").once('value').then(function(zone){
order.zone = zone.val();
resolve();
})
}))
promises.push(new Promise((resolve) => {
admin.database().ref("orders/"+order_id+"/time_order_placed").once('value').then(function(time_order_placed){
order.time = time_order_placed.val();
resolve();
})
}))
//grab zone and time first
return Promise.all(promises).then(()=>{
return admin.database().ref(order.zone+"/wait_order_queue/"+order.id).set(order.time);
})
}
JSON Firebase
"c98" : {
"orders" : {
"0333" : 123123,
"0345" : 12,
"0911" : 123,
"none" : "none"
}
稍微研究一下,也许可以应用到您当前的代码中。
想象一下 admin.database().ref("orders/"+order_id+"/time_order_placed").once('value')
就像 delay(time)
// let delay = time => new Promise(res=>setTimeout(res,time));
let delay = function(time){
return new Promise(function(resolve,reject){
setTimeout(function(){
resolve();
},time);
});
}
let myPromise = function(order){
return Promise.all([
delay(500),
delay(500),
delay(1000).then(function(){
console.log('Order complete: ',order);
return; // returns undefined, so cb doesn't pass anything to cb(err), but use ()=>cb() to avoid this anyways.
})
]);
}
let orders = [1,2,3];
async.each(orders,function(order,cb){
myPromise(order)
.then(()=>cb())
.catch(err=>cb(err));
},function(err,data){
if(err){
console.log('Err',err);
}else{
console.log('all Finished');
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/async/2.6.0/async.js"></script>