0

当我尝试多次更新用户字段时出现猫鼬错误。我想要实现的是在对外部资源进行 API 调用后根据某些条件更新该用户。根据我的观察,我在processUser()函数中同时达到了这两个条件,因此,user.save()几乎同时被调用,而 mongoose 不高兴向我抛出这个错误:

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)

4

1 回答 1

0

您的代码中有一些问题需要解决。

1) processUser 是一个异步函数。Array.prototype.forEach不尊重MDN 上记录的异步函数。

2) setInterval 不尊重您的函数的返回值,如MDN 上所述,因此传递一个返回承诺 (async/await) 的函数将不会按预期运行。

3) setInterval 不应与运行时间可能比您的时间间隔更长的函数一起使用,如页面底部附近的MDN上所述。Usage Section

在最好的情况下,每 2 秒为每个用户打一个外部 api 并对结果做出反应将是有问题的。我会首先问自己这是否绝对是实现我的总体目标的唯一方法。

如果这唯一的方法,您可能希望使用setTimeout()上面 #2 中的链接中提到的递归来实现您的解决方案,或者使用setInterval() npm here 上的异步版本

于 2020-05-06T12:32:00.697 回答