【问题标题】:Javascript async/await : undefined error on file readJavascript异步/等待:文件读取未定义错误
【发布时间】:2018-10-23 07:36:54
【问题描述】:

我正在尝试使用 async/await 发送带有 for 循环的电子邮件。

const prepareNotification =(genie)=>{
    genie.forEach(async (item)=>{
        if(item.is_active){

            if(item.is_email){
                sendEmailNotification(item);
            }

        }else{
            console.log('deal genie inactive for',item.name);
        }
    });
}

为了发送,我需要从文件中读取 HTML 并发送到邮件功能。

const sendEmailNotification=async (item)=>{
    try{

        let emailTemplate = await fs.readFile(__basedir+'/controllers/html/sharedeal.html','utf-8');
        console.log(emailTemplate);
        let replacements = {
            dealLink:'testlinkhere'
           };
        let mailOptions = {
                   from: process.env.smtpEmail,
                   to: item.email,
                   subject: 'DealLink',
                   replacements:replacements,
                   template:emailTemplate
           };
        let mail = await sendEmail(mailOptions);
    }catch(error){
      console.log(error);
   }
}

但我在console.log(emailTemplate); 上得到undefined,还有一个问题我如何确保sendEmailNotification 在for 循环中的每个状态上一个接一个地执行??

【问题讨论】:

  • Array.forEach 不支持async。或者,如果您想以另一种方式看到它,它确实不支持将 Promise 作为回调响应。您需要执行 ordered async loop 或类似的操作,否则将无法正常工作。此外,你应该做await sendEmailNotification,否则异步将无用。
  • 所以我需要在异步库的waterfall 方法中使用类似的东西
  • 无论您要使用什么,都可以通过执行一个简单的递归循环来实现:pastebin.com/mZbCi5UB。
  • 你答应fs.readFile了吗?它通常不会返回承诺。
  • 确实,fs.readFile 是同步的,除非被承诺...

标签: javascript node.js async-await file-read


【解决方案1】:

fs.readFile 不支持async/await。但是您可以创建一个版本:

const util = require('util');
const readFileAsync = util.promisify(fs.readFile);

然后

let emailTemplate = await readFileAsync(__basedir+'/controllers/html/sharedeal.html','utf-8');
console.log(emailTemplate);

如何确保 sendEmailNotification 在 for 循环中的每个状态上一个接一个地执行??

const prepareNotification = async (genie) => {
    for (let item of genie) {
        if(item.is_active){

            if(item.is_email){
                await sendEmailNotification(item);
            }

        }else{
            console.log('deal genie inactive for', item.name);
        }
    }
}

或

const prepareNotification = (genie) => {
    genie.reduce((prev, item) => {
        if(item.is_active){

            if(item.is_email){
                return prev.then(() => sendEmailNotification(item));
            }

        }else{
            console.log('deal genie inactive for', item.name);
        }
        return prev;
    }, Promise.resolve());
}

【讨论】:

  • 它的工作顺便说一句你对我的最后一句话有什么建议吗??
  • 不需要从sendEmailNotification返回promise??
  • @iambatman 它已经返回了一个Promise,它是一个async 函数。
猜你喜欢
  • 2020-05-30
  • 1970-01-01
  • 2021-07-27
  • 2018-06-18
  • 1970-01-01
  • 2019-08-07
  • 2020-09-13
  • 2018-12-20
  • 2022-01-04
相关资源
最近更新 更多