запустить функцию Synchouse в обещании - PullRequest
3 голосов
/ 25 мая 2019

Я новичок в JS и асинхронных операциях. В маршрутизаторе nodeJS, использующем Express, я собрал некоторые данные из mongo, используя mongoose. Данные - это данные о погоде, собираемые с разных мест каждые 15 минут. Я обработал данные с помощью агрегатного конвейера mongoose, чтобы получать почасовые данные и группировать их по каждому сайту. Но данные нуждаются в дополнительном процессе, чтобы получить периоды, когда относительная влажность превышает 90%, и присвоить баллы каждому периоду, поэтому я написал несколько синхронных функций, которые нацелены на каждый сайт (каждый объект геоджон).

Мангуст выглядит примерно так:

module.exports.filteredData = function (collection, dateInput) {
return collection.aggregate([

    {
        $addFields :{
            DateObj: {
                $dateFromString: {
                    dateString: "$DateTime",
                    format: '%Y-%m-%d'
                }
            },
        }
    },

    {
        $addFields :{
            NewDateTimes: {
                $dateFromParts:{
                    'year': {$year: '$DateObj'},
                    'month':{$month: '$DateObj'},
                    'day':{$dayOfMonth: '$DateObj'},
                    'hour': {$toInt: "$Time"}
                }
            }
        }
    }

...

синхронных функций:

const calcDSV = function(featuresJSON){

    // featuresJSON  
    const SVscore = [];
    const tuEval = featuresJSON.features.properties.TU90; // array
    const obArr = featuresJSON.features.properties.OB; // array
    const periodObj =  getPeriods(tuEval);// get period position
    const paramObj =  getParams(periodObj, obArr); // get parameters
    const periodDate =   getPeriodDate(featuresJSON, periodObj);
    const removeTime =  periodDate.beginDate.map(x=>x.split('T')[0]);


    let hourly = paramObj.hourCounts;
    let avgTemps = paramObj.avgTemps;


    for(let i = 0;i<hourly.length; i++){

        let score =  assignScore(avgTemps[i], hourly[i]);
        SVscore.push(score);

    }

    // output sv score for date


    const aggreScore =  accumScore(removeTime, SVscore);


    aggreScore.DSVdate = aggreScore.Date.map(x=>new Date(x));


    featuresJSON.features.properties.periodSV = SVscore;
    featuresJSON.features.properties.Periods = periodDate;
    featuresJSON.features.properties.DSVscore = aggreScore;

    return  featuresJSON;

}

Теперь я застрял на том, как применить эти функции на каждом сайте, возвращаемом конвейером агрегации mongoose по запросу:

router.post('/form1', (req, res, next)=>{

const emdate = new Date(req.body.emdate);
const address = req.body.address;
const stationDataCursor = stationData.filteredData(instantData, emdate);

stationDataCursor.toArray((err, result)=>{
    if(err){
        res.status(400).send("An error occurred in Data aggregation")
    };


    res.json(result.map(x=>calcDSV.calcDSV(x)));


})


});

Я пробовал в обратном вызове:

stationDataCursor.toArray((err, result)=>{
    if(err){
        res.status(400).send("An error occurred in Data aggregation")
    };


    res.json(result.map(async (x)=>await calcDSV.calcDSV(x))));


})

и использование then ():

stationDataCursor.toArray().then((docArr)=>{

    let newfeature = await docArr.map(async (x)=> await calcDSV.calcDSV(x))));


    res.json(newfeature);

})

или make calcDSV () возвращает новое обещание

    return  new Promise((rej, res)=>{
            resolve(featuresJSON);
     })

Я ожидаю увидеть все сайты с новой функцией, добавленной в ответ HTTP. Но большую часть времени я получал ReferenceError: ошибка не определена.

1 Ответ

1 голос
/ 27 мая 2019

Думаю, я понял:

  1. , в конце концов, нужно сделать все синхронные функции асинхронными, добавив асинхронность к этим функциям;
  2. переписать эту часть вфункция post router, особенно часть карты массива.Я прочитал от это .и в map() придется попытаться ... поймать ... в этом, иначе это не сработает.

    await stationDataCursor.toArray().then(async (docArr)=>{
    
            const newfeature = await Promise.all(docArr.map(async function(x){
                try{
                    const feature = await calcDSV.calcDSV(x);
    
                    return feature
                } catch(err){
                    console.log("Error happened!!! ", err);
    
                }
    
            }));
    
            res.json(newfeature)
    
    })
    

Надеюсь, это поможет.

...