簡體   English   中英

代碼停滯在collection.find

[英]Code stalling at collection.find

我是JS的新手,現在停留在這里。 我試圖在開始新查詢之前清除數據庫,並且它始終停滯在collection.find命令中。 如果刪除代碼以清除數據庫,一切正常。

router.get('/parse', function(req, res) {
    collection.remove({})
    collectionweb.remove({})
    collectionhit.remove({})
    //Converter Class
    var Converter = require("csvtojson").core.Converter;
    var fs = require("fs");
    var csvFileName = "./download/company.csv";
    var fileStream = fs.createReadStream(csvFileName);
    //new converter instance
    var param = {};
    var csvConverter = new Converter(param);
    request({
        uri: "http://online.barrons.com/news/articles/SB50001424053111904537004580085820431503044?mod=BOL_twm_fs",
    }, function(error, response, body) {
        collectionweb.insert({
            "website": body
        });
    });
    //end_parsed will be emitted once parsing finished
    csvConverter.on("end_parsed", function(jsonObj) {
        //Insert into DB
        collection.insert(jsonObj);
    });
    fileStream.pipe(csvConverter);
    collectionweb.find({}, function(e, docs1) {
        for (var j in docs1) {
            var body = docs1[j]
            var webs = body.website
            console.log(1)
            collection.find({}, function(e, docs) {
                for (var i in docs) {
                    console.log(2)
                    var companies = docs[i]
                    var Score = 0;
                    $words = webs.search(companies.Symbol);
                    console.log(3)
                    if ($words > 0) {
                        StockScore++console.log(Score)
                        collectionhit.insert(companies)
                        collectionhit.update({
                            "Name": companies.Name
                        }, {
                            '$set': {
                                "score": Score
                            }
                        })
                    } else {};
                };
            });
        };
    });
});

有很多問題,但是它們有一個共同點:您還不了解Node.js是異步的。 只是使用Google“異步的node.js”,您將獲得少量資源,或者只是在SO上查找它(例如, 如何開始使用Node.js? )。

要點是等待回調或事件,例如:

var eiot = new EventedIOThing('paaarammm');

// use once, unless you for sure need to listen for the event multiple times
eiot.once('open',function onEIOTOpen() {
    console.log('opened the thing.');
}).once('error',function onEIOTError(err) {
    console.warn('there were problemzzz');
}).once('end',function onEIOTEnd() {
    // successfully finished evented IO thing...
    someAction(this.dep,'anotherparam',function callMeWhenActionIsDone(err,result) {
        if ( err ) {
            console.warn('someAction had a problem!',err);
            return; // exit early if we didn't get an optimal result
        }
        anotherDependentAction(result,function callMeWhenSecondActionIsDone(err,result) {
            if ( err ) { // this 'err' is local to this function's scope
                console.warn('anotherDependentAction had a problem!',err);
                return; // exit early again
            }
            console.log('All done... what do you want to do next?');
        });
    });
});

給定變量/函數名稱和注釋,以上代碼是很容易解釋的,但是要特別注意方法的調用方式,尤其是調用方法時。 事情不會連續發生,而是代碼處於“備用”狀態,直到相關/正確的事情發生並獲得成功的結果,然后程序流才繼續。

上面的編碼風格的缺點是,您最終將獲得許多嵌套函數。 這就是異步之類的庫發揮作用的地方。 它允許淺的函數程序流:您指定一個函數數組,並在應該在內部調用回調時異步處理,您只需要擔心序列。

現在,使用您當前擁有的代碼,我們從第一個示例中學到的內容,並通過引入async模塊對其進行1-up操作,可以將其重寫如下:

var async = require('async'), // https://github.com/caolan/async
    fs = require('fs'),
    Converter = require('csvtojson').core.Converter;

router.get('/parse',function cbGetParse(req, res) {
    async.series([
        collection.remove.bind(collection),
        collectionweb.remove.bind(collectionweb),
        collectionhit.remove.bind(collectionhit),
        function convertCsv(callback) {
            var cbCalled = false; // i don't trust csvtojson to handle errors properly
            fs.createReadStream('./download/company.csv')
                .once('error',function(err) {
                    if ( !cbCalled ) {
                        cbCalled = true;
                        callback(err,null);
                    }
                })
                .pipe(new Converter({})) // pipe returns an instance of the Converter object
                .once('end_parsed',function onConverterEnd(jsonObj) {
                    collection.insert(jsonObj,function cbCollInsert(err,result) {
                        if ( !cbCalled ) {
                            cbCalled = true;
                            callback(err,result);
                        }
                    });
                });
        },
        function barronsHttpRequest(callback) {
            request({
                uri: 'http://online.barrons.com/news/articles/SB50001424053111904537004580085820431503044?mod=BOL_twm_fs',
            },function cbRequest(err,response,body) {
                if ( err ) {
                    callback(err,null);
                    return; // if err, exit early
                }
                collectionweb.insert({'website':body},function cbCollWebInsert(err,result) {
                    callback(err,result);
                });
            });
        },
        function lastChunkOfCode(callback) {
            // not going to rewrite this, same principle applies as above
            collectionweb.find({}, function(e, docs1) {
                for (var j in docs1) {
                    var body = docs1[j]
                    var webs = body.website
                    console.log(1)
                    collection.find({}, function(e, docs) {
                        for (var i in docs) {
                            console.log(2)
                            var companies = docs[i]
                            var Score = 0;
                            $words = webs.search(companies.Symbol);
                            console.log(3)
                            if ($words > 0) {
                                StockScore++console.log(Score)
                                collectionhit.insert(companies)
                                collectionhit.update({
                                    "Name": companies.Name
                                }, {
                                    '$set': {
                                        "score": Score
                                    }
                                })
                            } else {};
                        };
                    });
                };
                callback();
            });
        }
    ],function asyncComplete(err,result) {
        // you don't specify how to respond to the request so...
        if ( err ) {
            console.warn('Problem with /parse:',err);
        }
        res.end();
    });
});

我做了一個廢話噸在你的腳本應該如何工作的假設,因此它可能不是你想要的100%,但異步概念得到了應用。 另外,我沒有測試此代碼。 您需要確定可以並行運行還是串行運行,控制流應該是什么樣,以及如何處理錯誤(錯誤確實會發生)。

請注意,由於我無法弄清楚您的集合關系是什么,因此我並未在腳本的最后一個塊中實現異步行為-我也不會為您做所有工作。 我確實注意到它可以進行一些優化。 我看不出有任何理由要從兩個集合中選擇所有文檔。 您需要將選擇器/查詢處理卸載到數據庫上,如果可以幫助的話,它不應該存在於您的應用程序中。

一些要點:

  • Collection.remove (doc)接受回調,然后使用它。
  • Collection.insert (doc)相同-盡管文檔說回調是可選的,但僅在極少數情況下應將其省略。 (我不在乎您是否在使用寫問題。)
  • 注意您的for循環:
  • 永遠不要使用for...in ,尤其是對於數組,請使用常規的forArray.forEach
  • for任何異步調用使用任何類型的for循環時(尤其是與套接字相關的,例如MongoDb),您需要保持耐心並等待回調,否則您將充斥套接字(例如拒絕服務攻擊)。 我建議使用async.eachSeriesasync.eachLimit
  • 我喜歡給我的Lambdas(oxymoron?)命名,這有助於剖析堆棧跟蹤。
  • 請使用"' ,它們的作用完全相同,請勿混用。
  • 分小塊發展。 讓一部分工作,然后再進行下一部分,然后再進行下一部分。 工作小而抽象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM