2016-12-20 9 views
0

.forEachを使用してfirebaseオブジェクトよりもいくつかのループを完了しようとしていますが、私も約束しています。これは私がそれをどのように計画しているのか分かりません。私の基本的な問題は、約束のチェーン自体が完成した後、私の約束の中のループが完全に完了することです。ここに私の機能は次のとおりです。node.js内のループを完了すると約束します

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); 
}); 

そして、ここでは、出力されます。

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] 

私は私が間違って約束を使用するかもしれないと思うが、私は知りません。

+0

私はfirebaseを使ったことはありませんでしたが、誤って '.once'を使っているようです。少なくとも[これらのドキュメント](https://firebase.google.com/docs/database/web/read-and-write)によると、あなたは '.on( 'value、fn).then' ...) 'の代わりに' .once'を使用します。それとは別に、 'forEach'は' undefined'を返すので、おそらくあなたはそれよりも意味のある何かを返す/解決するつもりです。おそらく 'Array.prototype.map'を見てください。申し訳ありませんが私はより多くの助けができませんでした。 – naomik

答えて

0

forEachループが完了するのを待つためにPromise.all()を使用しているはずです。ここで私の問題を解決するために使用したコードは次のとおりです。

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); 
}); 
関連する問題