Функция для возврата ненулевого значения не работает должным образом при сохранении данных в MongoDB - PullRequest
0 голосов
/ 06 сентября 2018

Я получаю массив объектов из вызова API, а затем фильтрую значения в зависимости от двух ключей: story_title и title. Если оба значения равны нулю, объект фильтруется. Затем я перебираю отфильтрованный массив объектов, чтобы сохранить определенные данные в фильтре mongodb (используя mongoose). Проблема в том, что я хочу сохранить документ с одним ключом title, поэтому я создал функцию, которая проверяет, является ли story_title или title нулевым, и возвращает ненулевое значение.

Функция не работает должным образом, потому что функция в title внутри цикла for возвращает некоторые значения null.

function pickTitle(title, story_title) {
    if (!story_title) {
        return story_title;
    } else {
        return title
    }
}

everyHour: async () => {
        try {
            data = await axios.get(url);
            let posts = data.data.hits;
            const filteredPosts = await posts.filter((elem) => {
                return (!elem.title || !elem.story_title)
            });

            for (let filtered of filteredPosts) {
                Post.updateOne({
                    _id: filtered.objectID,
                    author: filtered.author,
                    title: await pickTitle(filtered.title, filtered.story_title),
                    created_at: filtered.created_at,
                    },
                    {$setOnInsert: filtered}, 
                    {upsert: true}, 
                    function(err, numAffected) {
                        if (err) {
                            //console.log("err")
                        } else {
                            //console.log(numAffected)
                        }
                    })
                    .then(res => {
                        //console.log(res)
                    })
                    .catch(err => {
                        //console.log(err)
                    });
            }
        } catch(error) {
            console.log(error);
        }
    }

1 Ответ

0 голосов
/ 06 сентября 2018

Здесь есть несколько вопросов. Я расскажу о них в некоторых комментариях в коде, а также в разделе «решение» прямо под комментарием к коду.

  • Вы ожидаете вызовов, которые не являются асинхронными ... не делайте этого. Array.filter не является асинхронной операцией
  • Ваша функция pickTitle редактируется await, когда она не асинхронна
  • Ваше решение обещаний внутри цикла, что обычно считается плохой практикой. Добавьте свои обещания в массив и разрешите всех с помощью Promise.all()
  • И, наконец, ваша логика «filter» фильтрует NULL title ИЛИ story_title. Это означает, что только один должен быть верным. Вполне возможно, что оба могут быть NULL, хотя. Таким образом, ваша функция pickTitle возвращает нулевое значение, если оба значения равны NULL. Если вы хотите, чтобы у было по крайней мере , одно из них содержало значение, вам нужно изменить способ работы вашего array.filter.

const pickTitle = (title, story_title) => {
  if (!story_title) {
    return story_title;
  }
  return title;
};

async () => {
  try {
    data = await axios.get(url);
    const posts = data.data.hits;
    // const filteredPosts = await posts.filter(elem => (!elem.title || !elem.story_title));  <-- you are awaiting on a filter... don't do that
    const filteredPosts = posts.filter(elem => (!elem.title || !elem.story_title));
    const filteredPostAnotherWay = posts.filter(post => { // <-- This might be more of what you want...
      let allowed = false;
      if (!post.title) {
        allowed = true;
      }
      if (!post.story_title) {
        allowed = true;
      }

      return allowed;
    });
    const postUpdates = [];

    for (const filtered of filteredPosts) {
      // Post.updateOne({   <-- You are resolving promises inside a for loop.  While it may work, it's generally not advised to do this.  Resolve everything with promise.all instead....
      //   _id:        filtered.objectID,
      //   author:     filtered.author,
      //   title:      await pickTitle(filtered.title, filtered.story_title),
      //   created_at: filtered.created_at,
      //   story_url:  filtered.story_url
      // },
      // { $setOnInsert: filtered },
      // { upsert: true },
      // (err, numAffected) => {
      //   if (err) {
      //     // console.log("err")
      //   } else {
      //     // console.log(numAffected)
      //   }
      // })
      //   .then(res => {
      //     // console.log(res)
      //   })
      //   .catch(err => {
      //     // console.log(err)
      //   });

      postUpdates.push(
        Post.updateOne({
          _id:        filtered.objectID,
          author:     filtered.author,
          // title:      await pickTitle(filtered.title, filtered.story_title), // <-- You are awaiting a non asynchronous function... why?
          title:      pickTitle(filtered.title, filtered.story_title),
          created_at: filtered.created_at,
          story_url:  filtered.story_url
        },
        { $setOnInsert: filtered },
        { upsert: true },
        (err, numAffected) => {
          if (err) {
          // console.log("err")
          } else {
          // console.log(numAffected)
          }
        })
      );
    }

    return Promise.all(postUpdates);
  } catch (error) {
    console.log(error);
  }
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...