2016-12-20 3 views
0

Ich versuche, ein paar Schleifen über Firebase-Objekte mit .forEach abzuschließen, und ich verwende auch Versprechungen. Das funktioniert nicht so, wie ich es geplant hatte. Mein grundlegendes Problem ist, dass die Schleifen innerhalb meiner Versprechen gut abschließen, nachdem die Versprechungskette abgeschlossen ist. Hier ist meine Funktion:Schleifen innerhalb von node.js Versprechungen abzuschließen

var queue = new Queue(productUpdateQueue, function(data, progress, resolve, reject) { 

    var incomingUpdateData = data; 
    var receiptID = incomingUpdateData.receiptID; 
    var userID = incomingUpdateData.userID; 
    var oldProductID = incomingUpdateData.oldProductID; 
    var newProductID = incomingUpdateData.newProductID; 
    var newReceipt = incomingUpdateData.newReceipt; 

    var postID = ""; 

    var updateObject = {}; 

    updateObject['usersPrivate/'+userID+'/receipts/'+receiptID+'/items/'+oldProductID] = null; 
    updateObject['usersPrivate/'+userID+'/receipts/'+receiptID+'/items/'+newProductID] = newReceipt; 

    clicks.child('VigLink').orderByChild('item').equalTo(oldProductID).once('value', function(cuidSnapshot) { 
     return cuidSnapshot.forEach(function(cuidSnapshot) { 
      var cuid = cuidSnapshot.key; 
      updateObject['clicks/VigLink/'+cuid+'/item'] = newProductID; 
      console.log('one'); 
      progress(20); 
     }); 
    }).then(function() { 
     return userReceiptMetrics.child(userID).child('receipts').child(receiptID).child('items').child(oldProductID).once('value', function(oldSnapshot) { 
      var data = oldSnapshot.val() 
      updateObject['userReceiptMetrics/'+userID+'/receipts/'+receiptID+'/items/'+oldProductID] = null 
      updateObject['userReceiptMetrics/'+userID+'/receipts/'+receiptID+'/items/'+newProductID] = data 
      if (data != null) { 
       updateObject['userReceiptMetrics/'+userID+'/receipts/'+receiptID+'/itemIDs/'+newProductID] = now 
       updateObject['userReceiptMetrics/'+userID+'/receipts/'+receiptID+'/itemIDs/'+oldProductID] = null 
      }; 
      console.log('two'); 
      progress(40); 
     }); 
    }).then(function() { 
     return userReceiptMetrics.child(userID).child('shops').child(oldProductID).once('value', function(oldSnapshot) { 
      var data = oldSnapshot.val() 
      updateObject['userReceiptMetrics/'+userID+'/shops/'+oldProductID] = null; 
      updateObject['userReceiptMetrics/'+userID+'/shops/'+newProductID] = data; 
      if (data != null) { 
       updateObject['userReceiptMetrics/'+userID+'/shopIDs/'+newProductID] = now; 
       updateObject['userReceiptMetrics/'+userID+'/shopIDs/'+oldProductID] = null; 
      }; 
      console.log('three'); 
      progress(60); 
     }); 
    }).then(function() { 
     posts.once('value', function(postSnapshot) { 
      // use Promise.all and Array#map to wait for all these queries to finish 

      var allPosts = postSnapshot.val() 
      var postKeys = Object.keys(allPosts) 

      return Promise.all(postKeys.map(function(postKey) { 
       var postID = postKey; 

       return posts.child(postID).child('items').child(oldProductID).once('value', function(itemSnapshot) { 

        return itemSnapshot.forEach(function(itemSnapshot) { 
         var itemData = itemSnapshot.val() 
         console.log('post snapshot'+ itemData); 
         updateObject['posts/'+postID+'/items/'+oldProductID] = null 
         updateObject['posts/'+postID+'/items/'+newProductID] = itemData 
        }); 
       }); 
      })); 
     }); 
    }).then(function() { 
     // Move to next item 
     return console.log('hey look here'+updateObject['posts/'+postID+'/items/'+newProductID]); 
     return firebaseRoot.update(updateObject, function(error) { 
      if (error) { 
       console.log("Error updating data:", error); 
       reject() 
      } else { 
       progress(100); 
       // resolve(); 
       console.log('four'); 
      } 
     }); 
    }).then(function() { 
     // Move to next item 
     return console.log('second one'+updateObject['posts/'+postID+'/items/'+newProductID]); 
     return firebaseRoot.update(updateObject, function(error) { 
      if (error) { 
       console.log("Error updating data:", error); 
       reject() 
      } else { 
       progress(100); 
       // resolve(); 
       console.log('four'); 
      } 
     }); 
    }); 

    // Finish the task asynchronously 
    setTimeout(function() { 
     reject(); 
    }, 10000); 
}); 

Und hier ist der Ausgang:

one 
two 
three 
hey look hereundefined 
second oneundefined 
post snapshot[object Object] 
post snapshot[object Object] 
post snapshot[object Object] 
post snapshot[object Object] 
post snapshot[object Object] 
post snapshot[object Object] 
post snapshot[object Object] 
post snapshot[object Object] 

Ich glaube, ich könnte Versprechen falsch verwenden, aber ich weiß es nicht.

+0

Ich habe noch nie Firebase zuvor verwendet, aber es sieht aus wie Sie ".once" falsch verwenden; zumindest nach [diese Dokumente] (https://firebase.google.com/docs/database/web/read-and-write) - ich denke, du meinst '.on ('value, fn). ...) 'statt' .once'. Abgesehen davon gibt 'forEach'' undefined' zurück, also solltest du wahrscheinlich etwas aussagekräftiger zurückgeben/lösen. Vielleicht sehen Sie sich 'Array.prototype.map' an. Entschuldigung, ich könnte nicht mehr Hilfe sein. – naomik

Antwort

0

Ich fand heraus, dass ich Promise.all() verwenden sollte, um zu warten, bis meine forEach-Schleifen abgeschlossen sind. Hier ist der Code, den ich verwendet, um mein Problem zu lösen, genießen:

var queue = new Queue(productUpdateQueue, function(data, progress, resolve, reject) { 

    var incomingUpdateData = data; 
    var receiptID = incomingUpdateData.receiptID; 
    var userID = incomingUpdateData.userID; 
    var oldProductID = incomingUpdateData.oldProductID; 
    var newProductID = incomingUpdateData.newProductID; 
    var newReceipt = incomingUpdateData.newReceipt; 

    var postID = "-KZOO0UII67uOmYo6DJh"; 

    var postKeys = []; 

    var updateObject = {}; 

    updateObject['usersPrivate/'+userID+'/receipts/'+receiptID+'/items/'+oldProductID] = null; 
    updateObject['usersPrivate/'+userID+'/receipts/'+receiptID+'/items/'+newProductID] = newReceipt; 

    return clicks.child('VigLink').orderByChild('item').equalTo(oldProductID).once('value', function(cuidSnapshot) { 
     return cuidSnapshot.forEach(function(cuidSnapshot) { 
      var cuid = cuidSnapshot.key; 
      updateObject['clicks/VigLink/'+cuid+'/item'] = newProductID; 
      progress(10); 
     }); 
    }).then(function() { 
     return userReceiptMetrics.child(userID).child('receipts').child(receiptID).child('items').child(oldProductID).once('value', function(oldSnapshot) { 
      var data = oldSnapshot.val() 
      updateObject['userReceiptMetrics/'+userID+'/receipts/'+receiptID+'/items/'+oldProductID] = null 
      updateObject['userReceiptMetrics/'+userID+'/receipts/'+receiptID+'/items/'+newProductID] = data 
      if (data != null) { 
       updateObject['userReceiptMetrics/'+userID+'/receipts/'+receiptID+'/itemIDs/'+newProductID] = now 
       updateObject['userReceiptMetrics/'+userID+'/receipts/'+receiptID+'/itemIDs/'+oldProductID] = null 
      }; 
      progress(25); 
     }); 
    }).then(function() { 
     return userReceiptMetrics.child(userID).child('shops').child(oldProductID).once('value', function(oldSnapshot) { 
      var data = oldSnapshot.val() 
      updateObject['userReceiptMetrics/'+userID+'/shops/'+oldProductID] = null; 
      updateObject['userReceiptMetrics/'+userID+'/shops/'+newProductID] = data; 
      if (data != null) { 
       updateObject['userReceiptMetrics/'+userID+'/shopIDs/'+newProductID] = now; 
       updateObject['userReceiptMetrics/'+userID+'/shopIDs/'+oldProductID] = null; 
      }; 
      progress(40); 
     }); 
    }).then(function() { 
     progress(55); 
     return posts.orderByChild('receipt').equalTo(receiptID).once('value'); 
    }).then(function(postSnapshot) { 
     return postSnapshot.forEach(function(post) { 
      progress(70); 
      postKeys.push(post.key) 
     }); 
    }).then(function() { 
     return Promise.all(postKeys.map(function(postKey) { 
      return posts.child(postKey).child('items').child(oldProductID).once('value', function(itemSnapshot) { 
       var itemData = itemSnapshot.val() 
       updateObject['posts/'+postKey+'/items/'+oldProductID] = null; 
       updateObject['posts/'+postKey+'/items/'+newProductID] = itemData; 
      }); 
     })).then(function(results) { 
      progress(85); 
      return results; 
     }); 
    }).then(function() { 
     return firebaseRoot.update(updateObject, function(error) { 
      if (error) { 
       console.log("Error updating data:", error); 
       reject() 
      } else { 
       progress(100); 
       resolve(); 
      } 
     }); 
    }); 

    // Finish the task asynchronously 
    setTimeout(function() { 
     reject(); 
    }, 10000); 
}); 
Verwandte Themen