【问题标题】:Update array list with a property issue使用属性问题更新数组列表
【发布时间】:2021-01-23 18:56:49
【问题描述】:

我正在尝试更新 userList... 中用户的数组列表,如果 userDetails.length 不为零,则拥有一个名为 valid 的属性。

但 userList 永远不会更新。

userList.map(async function(user) {
    let userId = user.id
    await db.queryUser(userId)
      .then(function(userDetails){
        if(userDetails.length !== 0){
          user.valid = true;
        }
    });
});

我试过这样做:

let filteredList = userList.map(async function(user) {
    let userId = user.id
    await db.queryUser(userId)
      .then(function(userDetails){
        if(userDetails.length !== 0){
          user.valid = true;
        }
    });
});

但承诺仍处于未决状态。有什么更好的方法吗?

更新

使用以下代码让它工作:

await Promise.all(userList.map(async function(user) {
    let userId = user.id
    await db.queryUser(userId)
      .then(function(userDetails){
        if(userDetails.length !== 0){
          user.valid = true;
        }
    });
  })
)

【问题讨论】:

    标签: javascript arrays object ecmascript-6 promise


    【解决方案1】:

    承诺正在等待,因为您从不等待它们。您只是在创建一个承诺地图。

    如果您想就地更新用户,则不需要地图:

    for (let user of userList) {
       const userDetails = await db.queryUser(user.id);
       if (userDetauls.length) user.valid = true;
    }
    

    (假设外部函数是异步的,否则使用.then而不是await

    更新 但是,这将以串行方式执行查询。也许您希望它们并行运行。

    在这种情况下,您可能想要实际绘制地图,然后使用 Promise.all 等待承诺。

    类似这样的:await Promise.all(userList.map(...));

    【讨论】:

    • 用户有时会返回一个 int 而不是对象...但是该对象确实存在于 userList 中并且可以正常打印。为什么会这样?
    • “用户返回一个 int”是什么意思?有时是什么?什么时候?你说的是 for...of 循环吗?
    • 让它工作。谢谢!最后一个问题,我应该在 Promise.all() 中使用 await 并在其中调用 promise 吗?请查看我对问题的编辑
    • await 只是.then 的一些语法糖,因此您只需要这两个选项之一。您可以写const userDetail = await db.queryUser()db.queryUser().then(userDetail => ...),两者都可以。如果你做await db.queryUser().then(...),它也会起作用,因为then 也返回一个Promise,但它是不必要的。关于Promise.all:它返回一个承诺。您需要等到它解决,这就是为什么您需要await 或使用.then 的原因。因此,是否要使用 await 或 then 取决于您,但有一个例外:您只能在 async 函数中使用 await
    • 还有一件事:如果map 不更新用户会更好,这是一个令人惊讶的副作用(例如,如果调用 getSomething() 会更新某些东西 - 你不会期待它)。也许您应该首先加载 userDetails,例如const userDetails = await Promise.all(userList.map(user => db.queryUser(user)),然后才使用 userDetails 更新用户。请注意,map 函数现在不需要异步,它只返回来自 queryUser 的 Promise。
    【解决方案2】:

    好吧,您似乎正在尝试使用 async/await 语法 with .then 语法而不是代替它。尝试在调用 queryUser 函数时将响应存储到变量 userDetails 中,然后像这样检查长度:

    let filteredList = userList.map(async function(user) {
        let userId = user.id
        let userDetails = await db.queryUser(userId)
    
        if(userDetails.length !== 0){
              user.valid = true;
            }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-22
      • 2020-02-03
      • 1970-01-01
      • 2011-05-22
      • 2018-02-17
      • 1970-01-01
      相关资源
      最近更新 更多