通过Node.js传递从承诺到承诺的价值

我试图传递一个对象,我使用Firebase承诺一个一个地构build。 如果有更好的方法逐步构build对象,我并不需要沿承诺链传递对象。 这是我的代码:

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() { return 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) { itemSnapshot.forEach(function(itemSnapshot) { var itemData = itemSnapshot.val() console.log('post snapshot'+ itemSnapshot); updateObject['posts/'+postID+'/items/'+oldProductID] = null updateObject['posts/'+postID+'/items/'+newProductID] = itemData }); }); })).then(function(results) { // put progress update in .then, and return the results progress(75); return results; }); }); }).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'); } }); }); // Finish the task asynchronously setTimeout(function() { reject(); }, 10000); }); 

输出是:

 one two three hey look hereundefined 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] 

任何和所有的帮助是超级赞赏。

你需要改变你的.then(现在改成了这个问题,但代码原来是这样的)

 }).then(function(updateObject) { 

 }).then(function() { 

以便您的代码始终更新在new Queuecallback中声明的updateObject

而且,每一行的第一行都需要添加一个返回

所以,而不是

 userReceiptMetrics.child(userID).child('receipts').child(receiptID).child('items').child(oldProductID).once('value', function(oldSnapshot) { 

你有

 return userReceiptMetrics.child(userID).child('receipts').child(receiptID).child('items').child(oldProductID).once('value', function(oldSnapshot) { 

进度调用需要放在.oncecallback的末尾

总之,代码应该看起来像(删除了大部分正确的代码,希望这是可以理解的

 var queue = new Queue(productUpdateQueue, function(data, progress, resolve, reject) { // removed for brevity var updateObject = {}; // removed for brevity clicks.child('VigLink').orderByChild('item').equalTo(oldProductID).once('value', function(cuidSnapshot) { // removed for brevity progress(12); }).then(function() { return userReceiptMetrics.child(userID).child('receipts').child(receiptID).child('items').child(oldProductID).once('value', function(oldSnapshot) { // removed for brevity progress(25); }); }).then(function() { return userReceiptMetrics.child(userID).child('shops').child(oldProductID).once('value', function(oldSnapshot) { // removed for brevity progress(50); }); }).then(function() { return posts.orderByChild('items').equalTo(oldProductID).once('value', function(postSnapshot) { // use Promise.all and Array#map to wait for all these queries to finish return Promise.all(postSnapshot.map(function(postSnapshot) { var postID = postSnapshot.key; return posts.child(postID).child('items').child(oldProductID).once('value', function(itemSnapshot) { itemSnapshot.forEach(function(itemSnapshot) { var itemData = itemSnapshot.val() updateObject['posts/'+postID+'/items/'+oldProductID] = null updateObject['posts/'+postID+'/items/'+newProductID] = itemData }); }); })).then(function(results) { // put progress update in .then, and return the results progress(75); return results; }); }); }).then(function() { // Move to next item console.log(updateObject); // removed for brevity }); // Finish the task asynchronously setTimeout(function() { reject(); }, 10000); }); 

所以我终于想出了如何做到这一点。 我有一个问题,一步一步传递对象的问题,但我真正想做的是一步一步创build对象。 所以我在promise链之外创build了这个对象,并且一步一步地构build它。 这里的主要障碍之一是让我的循环完成,然后继续下一步的承诺。 为了做到这一点,我使用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); });