Node Js Async Ожидание первого ответа Пусто - PullRequest
0 голосов
/ 18 января 2019

Я новичок в асинхронном / ожидающем кодировании в узле js. Я пытаюсь получить данные из mongodb, а затем заполнить результат в объект. Но здесь я сталкиваюсь со странной проблемой, когда я выхожу из сервера и снова включаю его, а затем нажимаю API в узле js, первый ответ всегда пуст. Я начинаю получать ответ, как только я нажимаю на API после 1-й попытки ниже, мой код

let resu={};

router.get('/getTarrifDetails',async (req,res,next) => {
  await Tarrif.find().distinct('tarrif_type',(err,docs) => {
    docs.forEach(async (ele) => {
      let count= User.countDocuments({tarrif_type:ele});
      result.push(ele);
      result[ele] = await count;
      result.push(count);
    });
  });

  getAll(res);
});

async function getAll(res) {
  if(await resu.length!=0) {
    res.send(resu);
  }
}

Ответы [ 2 ]

0 голосов
/ 18 января 2019

Ваш код неверный.

1) Не рекомендуется хранить контекстную переменную resu вне области запроса.

2) result.push? где переменная result? снова вне зоны видимости?

3) resu.length? это не массив, это объект, поэтому вы не получите false или 0 результата.

4) find().distinct('tarrif_type', (err,docs) => ... Мангуста поддерживает обещания, так почему Вы использовали его с обратным вызовом?

5) await resu.length? это не обещание, это просто объект, а длина - это свойство, вы не можете запросить await из атрибута не-обещания

6) getAll что если resu.length действительно будет иметь 0? на что это ответит? - поэтому запрос будет зависать, поэтому Вы должны ответить на все вопросы, чтобы изящно закрыть соединение, созданное во время запроса.


Так что общее исправление должно работать:

router.get('/getTarrifDetails', async (req, res) => {
  try {
    const tarrifTypes = await Tarrif.find().distinct('tarrif_type');

    const tarrifCounters = {};
    let total = 0;
    for(const tarrifType of tarrifTypes) {
      const count = await User.count({tarrif_type: tarrifType});
      tarrifCounters[tarrifType] = count;
      total+= count;
    }

    res.status(200).send({
      tarrifTypes,
      tarrifCounters,
      total
    });
  } catch(error) {
    res.status(500).send(error.message);
  }
});

или используя параллелизм:

const getTarrifUsersCounters = async (tarrifTypes) => {
  // initial result
  const result = {
    tarrifTypes,
    tarrifCounters: {},
    total: 0
  };

  // if no tarriffTypes passed return result
  if (!(Array.isArray(tarrifTypes) && tarrifTypes.length > 0)) {
   return result;
  }

  // generating array of promises from tarrifTypes
  const callStack = [];
  for(const tarrifType of tarrifTypes) {
    callStack.push(
      new Promise(async resolve => {
        const count = await User.count({tarrif_type: tarrifType});
        resolve({tarrifType, count});
      });
    );
  }

  // calling promises array in parallel
  if (callStack.length) {
    (await Promise.all(callStack))
      .forEach(
        ({tarrifType, count}) => {
          result.tarrifCounters[tarrifType] = count;
          result.total += count;
        });
  }

  return result;
};

router.get('/getTarrifDetails', async (req, res) => {
  try {
    const tarrifTypes = await Tarrif.find().distinct('tarrif_type');
    const result = await getTarrifUsersCounters(tarrifTypes);
    res.status(200).send(result);
  } 
  catch(error) {
    res.status(500).send(error.message);
  }
});
0 голосов
/ 18 января 2019

Необходимо убедиться, что оператор await завершен, прежде чем вы сможете сравнить. Помните, что async / await не заставляет код работать синхронно, он просто форматирует его таким образом, чтобы мы, разработчики, выглядели так, как будто он синхронизирован.

function findData() {
      return Tarrif.find().distinct('tarrif_type',(err,docs)=>{
          docs.forEach(async (ele)=>{
          let count= User.countDocuments({tarrif_type:ele});
          result.push(ele);
          resu[ele]=await count;
          result.push(count);
        });
      });
    };


router.get('/getTarrifDetails',async (req,res,next)=>{
    let res = null;
    try {
       res = await findData();
    } catch(e) {
      console.log(e);
    }
    if(res !== 0){
      //do something
    } else {
      // do something else
    }

});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...