javascript - 如何在异步函数中运行替换函数?

标签 javascript async-await

我有一个 MongoDB,我想更改一堆模板的值。

我想我得到了变量并替换了旧值。

  findTemplates.forEach(async templateName => {
     const template = await getTemplate( templateName )
     const templateBody = await replaceBody( template.body )
     templateBody.replace('string', 'another-string');
  })

  async function getTemplate (siteName) {
    const id = await emailTemplate.model.findOne({
      'name.de': siteName,
      language: 'en',
      businessUnit: '24ede462ad78fd0d4fd39dfa',
    }).distinct('_id')

    const body = await emailTemplate.model.findOne({
      '_id': id,
    }).distinct('body')

    return {
      id: id,
      body: body
    }
  }

  function replaceBody( body ) {
     return body.replace('one', 'two')
  }

不幸的是,我收到以下错误:

UnhandledPromiseRejectionWarning: TypeError: body.replace is not a functiontemplateBodyHow can I use the replace function in my forEach async function?

最佳答案

我重写了你的示例,所以我可以模拟它,这个示例按你的预期工作,但没有抛出异常。所以,我检测到的唯一错误是这一行:

 // You must not put await here because replace body does not return a Promise.
 const templateBody = replaceBody( template.body )

const allTemplates = []

for (let i = 0; i <= 10; i++) {
  allTemplates.push({
   _id: faker.random.uuid(),
   'name.de': faker.internet.domainName(),
   language: faker.random.locale(),
   businessUnit: faker.random.uuid(),
   body: faker.lorem.paragraph()
  })
}

const findTemplates = allTemplates.map(item => item['name.de'])

const emailTemplate = {
   model: {
      findOne: params => {
         const found = allTemplates.find(item => params._id ? item._id === params._id : item['name.de'] === params['name.de'])
         const result = Object.assign({}, found, params)

         result.distinct = function (key) {
          return Promise.resolve(this[key])
         }
         
         return result
      }
   }
}

async function getTemplate (siteName) {
  const id = await emailTemplate.model.findOne({
    'name.de': siteName,
     language: 'en',
     businessUnit: '24ede462ad78fd0d4fd39dfa',
  }).distinct('_id')

  const body = await emailTemplate.model.findOne({
    '_id': id,
  }).distinct('body')

  return {
    id: id,
    body: body
  }
}

function replaceBody( body ) {
   return body.replace('one', 'two')
}

findTemplates.forEach(async templateName => {
   try {
     const template = await getTemplate( templateName )
     // You must not put await here because replace body does not return a Promise.
     const templateBody = replaceBody( template.body )
     console.log(templateBody.replace('string', 'another-string'))
   } catch (err) {
     console.err(`Error procesing template: ${templateName}: ${err}`)
   }
})

/**
 * Alternatively you can do:

Promise.all(findTemplates.map(async templateName => {
   const template = await getTemplate( templateName )
   // You must not put await here because replace body does not return a Promise.
   const templateBody = replaceBody( template.body )
   console.log(templateBody.replace('string', 'another-string'))
}).catch(err => console.err)
*/
 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/Faker/3.1.0/faker.min.js"></script>

关于您的问题:如何在我的 forEach 异步函数中使用 replace 函数?答案是您可以像您一样使用替换(但修复该行,并检查@t-j-crowder 评论的内容)。

如果正文不是字符串,那么你应该检查它是什么类型的对象,它是否有一个替换函数(或没有),以及这个替换函数是否返回(或不返回)一个 Promise。

关于javascript - 如何在异步函数中运行替换函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58284525/

相关文章:

javascript - AWS IoT websocket 连接返回 403

c# - 非等待线程在 api 返回后停止执行,这是一个已知的错误,还是有人可以解释发生了什么?

javascript - JSSProvider 不使用 classNamePrefix 生成类前缀

javascript - 在 setState 中传递多个函数作为回调

c# - 如何正确阻止异步代码?

javascript - Facebook 登录不断重复询问权限 React Native?

c# - Pubnub 执行同步请求

c# - 为什么 EF 6 教程使用异步调用?

javascript - 使用 jQuery 区分接收 HTML 事件的节点

javascript - javascript中函数参数从哪里来?