如何处理Nodejs中的异步性?

时间:2018-06-14 20:45:00

标签: javascript node.js performance

我遇到这种情况,我需要将大量数据分类到不同的存储桶中。如果已经有某个数据类型的存储桶然后将其推入那里,但如果遇到的数据类型是新的,我需要为它创建一个需要数据库查询的新存储桶。这在理论上很好用。但是,我遇到的问题是在循环继续之前需要进行数据库查询,以便将来的数据插入到该存储桶中。如何在函数完成之前暂停循环?

我已经尝试了loop and callback approach并获得了我正在寻找的控制流程,但是数据太大而且我堆栈溢出。有没有其他方法可以解决这种控制流程?

编辑:添加代码与人们建议的承诺。它实际上运行良好,但只是在数据点8428处停止。据我所知,数据点并不特殊,并且所有桶都已在此时创建,因此它不会创建新的存储桶。它就停止了。有任何想法吗?也许是我如何调用next()而我错过了一个案例?

async function sortData(data, images, i) {
    let uuidList = [];
    //This loop will wait for each next() to pass the next iteration
    for (var j = 0; j < data.length; ++j) { 
        await new Promise(next=> {
            let pos = uuidList.map(function(e) { return e.uuid; }).indexOf(data[j].uuid);
            if(pos < 0){
                Instance_Type.findInstance(data[j]._instance_type, function(err, instance){
                    /* add new bucket here */
                    if(itemsProcessed == images.length) {
                        processBuckets(uuidList, threshold, function(){
                            console.log("Bucket finished");
                            dataPackage.push({
                                imageName: images[i].name,
                                uuidList: uuidList,
                            });
                            ++itemsProcessed;
                            if(itemsProcessed == images.length){
                                console.log("Rendering!");
                                res.render('data', {
                                    dataPackage: dataPackage
                                });
                            }
                        });
                    }
                    next();
                });
            } else {
                /*push to existing bucket here*/
                if(itemsProcessed == images.length) {
                    processBuckets(uuidList, threshold, function(){
                        console.log("Bucket finished");
                        dataPackage.push({
                            imageName: images[i].name,
                            uuidList: uuidList,
                        });
                        ++itemsProcessed;
                        console.log(itemsProcessed);
                        if(itemsProcessed == images.length){
                            console.log("Rendering!");
                            res.render('data', {
                                dataPackage: dataPackage
                            });
                        }
                    });
                }
                next();
            }

        })       
    }
}

3 个答案:

答案 0 :(得分:1)

您是否尝试过异步等待。 对于异步函数,您可以等待承诺在您的案例数据库调用中返回,一旦结算,您就可以转到下一个。请仔细检查并进行其他参考,这将有助于您的事业。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await

答案 1 :(得分:1)

如果我正确理解你的问题,我认为你可以通过使用Promise来实现它吗?如果你想定期运行东西,也可以将它与你可以设置/清除的间隔结合起来,以控制你想要循环停止/继续的时间。

如果不熟悉承诺我建议检查:

答案 2 :(得分:1)

就循环暂停而言,如果你有Node 7.6或更高版本。

&#xA;&#xA;
 让myData = [“a”,“b”,“ c“];&#xA;&#xA; // TODO:使用try catch&#xA;异步函数findMyBucket(){&#xA; for(let x = 0; x&lt; myData.length; x + = 1){&#xA; var resp = await checkCreateAndInsertInBucket(myData [x]); //循环暂停&#xA;的console.log(RESP);&#XA; }&#xA;}&#xA;&#xA; function checkCreateAndInsertInBucket(data){&#xA;返回新的Promise((解析,拒绝)=&gt; {&#xA; //数据库逻辑带有承诺或回调&#xA;解决(true); //或拒绝&#xA;});&#xA;} &#XA;&#XA; findMyBucket();&#XA;  
&#XA;