Как я могу получить данные из асинхронного вызова вместо получения undefined? - PullRequest
0 голосов
/ 07 августа 2020

subject в user.subjects = subjects ниже - это undefined вместо массива субъектов.

Предыстория: у меня есть три таблицы - пользователи, субъекты и отношения между пользователями и субъектами, называемые users_subjects.

Моя цель состоит в том, чтобы окончательный результат включал в себя массив имен субъектов.

Для этого мне нужно три асинхронных вызова.

  • Получить пользователей из таблица пользователей
  • Получить темы для каждого пользователя из таблицы, представляющей отношения между пользователями и субъектами (users_subjects)
  • Получить имя для каждого идентификатора субъекта из таблицы субъектов

Моя задача состоит в том, чтобы ввести идентификатор субъекта и получить имя. верхняя половина addSubjects - это моя попытка решить эту проблему, хотя и безуспешно:

   //for every user take its id
    //run its id with tutors-subjects to get all subject id with that user id
    //for each subject id get is subject name through with subjects service
    //add subjects key
    //add each subject to an array
const addSubject = (knexInstance, users, res) => {
  let resultsName = []
    function testIt(subjectsArray) {
       // let resultsName = []
        Promise.all(
            subjectsArray.map((id) =>
                SubjectsServes.getById(knexInstance, id)
                    .then(subjectNameObject => {
                       console.log(subjectNameObject)
                        resultsName.push(subjectNameObject.subject_name)
                    })
                    .catch(err => {
                        //console.log(err)
                    })
            )).then(() => {
                return resultsName
            })
    }

    let results = []

    Promise.all(
        users.map((user) =>
            TutorsSubjectsService.getAllSubjectsForATutor(knexInstance, user.user_id)
            .then(subjectsIdArray => {
                    return testIt(subjectsIdArray)
                })
                .then(sub => {
                    user.subjects = sub
                    results.push(user)
                })
                .catch(err => {
                    //console.log(err)
                })
        )).then(() => {

            return res.json(results)
        })
        .catch(err => {
            //console.log(err)
        })

}

Следующий код - это то место, где он начинается - он вызывает вышеуказанную функцию:

    .get((req, res, next) => {
        const knexInstance = req.app.get('db');
        UsersService.getAllUsers(knexInstance)
            .then(Users => {
                return addSubject(knexInstance, Users, res)
            })
            .catch(next)

Единственная проблема, с которой я столкнулся, связана с функцией testIt. Все до этого момента работает нормально. Они здесь только для контекста.

Мой вопрос в том, как мне получить правильные имена субъектов из testIt?

(возврат в testIt last then не помогает ; вся функция testI просто возвращает undefined как сказано в заголовке)

1 Ответ

1 голос
/ 07 августа 2020

const  testIt = (subjectsArray)=> {
       
        return subjectsArray.map((id) => {
            
               return SubjectsServes.getById(knexInstance, id);
               
            }).reduce((acc,el)=>{
            
                acc.push(el); 
                return acc;
                
               },[])
               
           //return array of promises
        
 }
const addSubject = (knexInstance, users, res) => {
  
   
    
    Promise.all(
        users.reduce((acc,el)=>{ 
           acc.push(TutorsSubjectsService.getAllSubjectsForATutor(knexInstance, el.user_id));              return acc; 
          
          },[])
           
        ).then((userResults) => { 
        //resolve all promises userResult is an array of result from promises above

            Promise.all( userResults.reduce((acc,el)=>{
               //for each user create array of promises given the subject list
               acc = acc.concat(testIt(el))
            } ,[]).then((results)=>{
            
               return res.status(200).send(result);
            }).catch( (err)=>{
            
              console.log(err);
              
              return res.status(500).end();
            } )
        })
        .catch(err => {
              console.log(err);
              
              return res.status(500).end();
        })

}

когда вы .then () это означает, что вы выполняете обещания. Так что ничего не верните на обещание. Promise.all().then( result=>{} ) result - это массив вывода из обещаний. Вы должны связать все обещания друг в друге. Это asyn c, 2 обещания выполняются одновременно. Таким образом, ваше имя результата будет неоднозначным, возможно, начальное значение (пустой массив)

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