【问题标题】:async / await not working as expected [duplicate]异步/等待未按预期工作[重复]
【发布时间】:2018-12-02 14:54:50
【问题描述】:

我的函数名为 createUser()

const createUser = () => {
    return new Promise(async (resolve, reject) => {
        var data = await Home.findAll({ raw: true })
        await data.forEach(async (client) => {
            await postgresDB.createSchema(client.code).then(async () => {
                await Object.keys(postgresDB.models).forEach(async (currentItem) => {
                    await postgresDB.models[currentItem].schema(client.code).sync();
                });
            });
        });
        resolve('Postgres schema created')
    });
} 

我的 nodejs api:

exports.createBusiness = (req, res) => {
  const business = {
    name: req.body.name,
    code: req.body.code,
    email: req.body.email,
  };
  Business.create(business)
    .then((rawbusinessData) => {
      createUser() // this needs to completed full then only i need to move to below then function


        .then(() => {
          const businessData = rawbusinessData.get({ plain: true });
          const loginDetails = {
            username: 'sameer',
            password: encrypt('sameer'),
          };
          postgresDB.models.login.schema(businessData.code).create(loginDetails)
            .then((loginData) => {
              console.log('loginData:', loginData);
              return res.status(200).send(loginData);
            }).catch((err) => {
              console.log('error while create schema:', err);
            });
        });
    })
    .catch((err) => {
      console.log('err:', err);
    });
};

不知道是什么问题,苦苦挣扎了三天多。

我使用的是正确的语法吗?还是只使用 Promise 好?

【问题讨论】:

标签: javascript node.js asynchronous callback promise


【解决方案1】:

forEach 返回 undefined, awaiting 不等待它迭代的异步函数。取而代之的是 map 到一系列承诺并使用 Promise.all 等待它们:

await Promise.all(Object.keys(postgresDB.models).map(async (currentItem) => {
      /*...*/
}));

在异步函数中另外使用new Promise 完全没有意义,如下:

const createUser = () => {
  return new Promise(async (resolve, reject) => {

其实可以:

async function createUser() {
  //...
}

然后只是return最后的结果。


你也必须

return User.create(loginDetails) 

这样它就会被链接到父 Promise 中。


我会怎么做:

async function createUser() {
  var data = await Home.findAll({ raw: true })
  await Promise.all(data.map(async (client) => {
    await postgresDB.createSchema(client.code)
    await Promise.all(Object.keys(postgresDB.models).map(currentItem => 

         postgresDB.models[currentItem].schema(client.code).sync();
    ));
  }));        
  return 'Postgres schema created';
} 

//------

exports.userSignup = async (req, res) => {
  try {
    await createUser();
    const loginDetails = {  username: 'stackoverflow' };
    const data = await User.create(loginDetails) 
    res.status(200).send(data);
  } catch(err) {
    console.log(err);
    res.status(500).send("")
 }
};

【讨论】:

  • 会检查并更新您,感谢您的回答。
  • 嗨,乔纳斯,你在吗?
  • 实际上我的 node api 已经退出大了,请参阅我的 node api 更新问题,我试过你的代码仍然异步工作
  • 请用我更新的问题更新你的答案,我一定会尝试告诉你,我挣扎了三天以上
  • @MohamedSameer “我挣扎了三天多” - 那么为什么在几分钟后没有反应的要求很高(“嗨,乔纳斯你在吗? ", "你在吗???....")? O.o
【解决方案2】:

你不能像 awaitforEach 这样 - 你需要将承诺映射到一个数组并使用 Promise.all 代替。此外,当您已经从另一个调用中获得 Promise 时,不要构造并返回 Promise - 相反,只需从其他调用中返回 Promise。

将两个forEachs 转换为Promise.all 调用。例如:

const createUser = async () => {
  var data = await Home.findAll({ raw: true });
  const clientPromises = data.map(async ({ code }) => {
    await postgresDB.createSchema(code);
    return Promise.all(postgresDB.models.map((currentItem) => (
      postgresDB.models[currentItem].schema(code).sync()
    )));
  });
  await Promise.all(clientPromises);
  console.log('Postgres schema created');
} 

【讨论】:

  • 会检查并更新您,感谢您的回答。
  • 不工作.....
  • 好像await Promise.all(clientPromises) 不见了
  • @MohamedSameer 我在其他需要的Promise.all中编辑了
猜你喜欢
  • 2021-12-08
  • 2019-04-19
  • 2020-03-04
  • 2019-04-07
  • 2018-05-05
  • 2022-01-22
  • 1970-01-01
  • 2021-07-15
  • 2023-03-03
相关资源
最近更新 更多