Одновременное обновление пользователя в mon goose с использованием model.save () вызывает ошибку - PullRequest
0 голосов
/ 05 мая 2020

Я получаю сообщение об ошибке mon goose, когда пытаюсь обновить пользовательское поле несколько раз. Чего я хочу добиться, так это обновить этого пользователя на основе некоторых условий после вызова API внешнего ресурса. Из того, что я наблюдаю, я одновременно выполняю оба условия в функции processUser(), поэтому user.save() вызывается почти одновременно, и mon goose недоволен тем, что это выдает мне эту ошибку:

MongooseError [ParallelSaveError]: Can't save() the same doc multiple times in parallel. Document: 5ea1c634c5d4455d76fa4996

Я знаю, что виноват, и виноват мой код, потому что я новичок. Но есть ли способ добиться желаемого результата без этой ошибки? Спасибо.

function getLikes(){
    var users = [user1, user2, ...userN]

    users.forEach((user) => {
        processUser(user)
    })
}

async function processUser(user){
    var result = await makeAPICall(user.url)
    // I want to update the user based on the returned value from this call
    // I am updating the user using `mongoose save()`

    if (result === someCondition) {
        user.meta.likes += 1
        user.markModified("meta.likes")

        try {
            await user.save()
            return
        } catch (error) {
            console.log(error)
            return
        }
    } else {
        user.meta.likes -= 1
        user.markModified("meta.likes")

        try {
            await user.save()
            return
        } catch (error) {
            console.log(error)
            return
        }
    }
}

setInterval(getLikes, 2000)

1 Ответ

0 голосов
/ 06 мая 2020

Есть некоторые проблемы, которые необходимо решить в вашем коде.

1) processUser - это асинхронная функция. Array.prototype.forEach не уважает асинхронные функции, как описано здесь, в MDN .

2) setInterval не учитывает возвращаемое значение вашей функции, как описано здесь, в MDN , поэтому передача функции, которая возвращает обещание (async / await), не будет вести себя должным образом.

3) setInterval не следует использовать с функциями, выполнение которых потенциально может занять больше времени, чем ваш интервал, как описано здесь, в MDN в Usage Section в нижней части страницы.

Нажатие внешнего API для каждого пользователя каждые 2 секунды и реакция на результат будет проблематичной c под лучшие обстоятельства. Я бы начал с вопроса, действительно ли это способ достижения моей общей цели только .

Если это - это единственный способ, вы, вероятно, захотите реализовать свое решение, используя рекурсивный setTimeout(), упомянутый в ссылке в # 2 выше, или, возможно, используя asyn c версия setInterval() там одна на npm здесь

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