繁体   English   中英

Node.js 控制台在 firebase 数据库引用后挂起

[英]Node.js console hangs after firebase database ref

我看过类似的问题,但没有一个解决方案对我有用。 我的代码非常简单(图 1),控制台只是挂起。 我可以在最后放入一个 process.exit() 并停止执行,但这不起作用,因为我需要在 for 循环中执行 ref(图 3)所以 process.exit() 不会在那里工作或者它只是立即停止执行。 我已经在很多地方尝试了 goOffline()、app().delete() 等很多东西,但它就是行不通。 它要么执行代码并挂起,要么不执行任何操作并停止。

挂起的简单代码:

firebaseApp = firebase.initializeApp(config);
var db = firebase.database().ref('\deals');

使用 process.exit() 停止程序但不执行数据库代码的代码:

firebaseApp = firebase.initializeApp(config);
var db = firebase.database().ref('\deals');
process.exit();

理想情况下我的目标:

firebaseApp = firebase.initializeApp(config);
var db = firebase.database()
for (var i=1; i < 5; i++){
    db.ref('\deals').on(do some stuff... )
}
// somehow need to exit when the loop completes, but it hangs

大图:我有一个简单的文本文件,我正在从中读取行,处理一些数据并将其存储在数组中。 所以我需要循环那个数组,并为每个元素检查数据库以查看它是否匹配(重复),如果是,则忽略它。 如果不是重复的,则将其添加到数据库中。 所以我的代码的更宏大的画面是:

firebaseApp = firebase.initializeApp(config);

const fs = require('fs'); 
fs.readFile('info1.txt', (err, data) => { 
    if (err) throw err; 
  
    var deal = data.toString().split("~");
    var i;
    for (i=0; i < deal.length; i++){
        var dealData = deal[i].split("\r\n");
        var newDealData = dealData.filter(function (el) {
            return el != '';
        });

        var category=newDealData[0];
        var asin=newDealData[1];

        firebaseApp.database().ref('\deals').on('value', (snapshot) => {
            snapshot.forEach((child) => {
                var compareAsin= child.val().asin;
                var compareCategory= child.val().category;
              if (compareAsin == asin && compareCategory == category){
                  isMatch=1;
              }
            })

            if (isMatch){
                console.log("uh oh duplicate");
            } else {
                writeDealData(asin, category);
            }
        })
    }
}) 

哦,天哪,我做到了,我想尖叫我觉得自己很聪明。 我重新组织了我的代码结构,这样数据库引用就不会被循环,而是在其中包含 for 循环。

var ref = firebase.database().ref("/deals");
ref.once("value")
  .then(function(snapshot) {
    fs.readFile('info1.txt', (err, data) => { 
        if (err) throw err;  
        var deal = data.toString().split("~");
        var i;
        for (i=0; i < deal.length; i++){
            var dealData = deal[i].split("\r\n");
            var newDealData = dealData.filter(function (el) {
                return el != '';
            });
            var category='';
            var asin='';
            var isMatch=0;
            snapshot.forEach((child) => {
                var compareAsin= child.val().asin;
                var comparePromo= child.val().promoCode;
              if (compareAsin == asin && comparePromo == promoCode){
                  isMatch=1;
              }
            })

            if (isMatch){
                console.log(`duplicate row ${i} asin ${asin}, not added`);
            } else {
                writeDealData(asin, cateogry);
            }
        }
        process.exit();
    })
});

为了使您的数据库查询快速且对所使用的资源有所了解,我建议在您的数据中存储一个组合索引字段: { "category-asin": "<category>-<asin>" }

这允许您查询数据库中的单个条目,而无需像当前代码那样下载整个数据库。 它还允许您在安全规则中对其进行索引

firebase.initializeApp(config);

// for the given category and asin, return entries that contain that exact category and asin value.
function lookupDeal(category, asin) {
  return firebase.database().ref('deals').orderByChild('category-asin').equalTo(`${category}-${asin}`).once('value');
}

const fs = require('fs');

fs.readFile('info1.txt', (err, data) => { 
    if (err) {
        console.error('File Error:', err);
        process.exit(1);
    }
  
    const deals = data.toString().split("~");
    
    Promise.all(deals.map((deal) => {
        const dealData = deal.split("\r\n"); // <-- might want to use /(\r?\n)+/ instead to support both \r\n and \n line endings, while also skipping empty lines
        const newDealData.filter((e) => e != '');

        const [category, asin] = newDealData;
        
        return lookupDeal(category, asin)
            .then((snapshot) => {
                if (snapshot.hasChildren()) {
                    console.log(`duplicate found for category="${category}" and asin="${asin}", skipping.`);
                    return;
                }
                
                return writeDealData(asin, category); // make sure this returns a promise!
            });
    }))
    .then((writeResults) => {
        console.log('All sync operations completed successfully. Exiting.');
        process.exit();
    })
    .catch((error) => {
        console.error('Database error:', error);
        process.exit(1);
    })
});

注意:可以通过将fs.readFile更改为 promise 形式来进一步改进此答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM