【问题标题】:How do I use async/await in a mocha before hook?如何在钩子前在摩卡咖啡中使用 async/await?
【发布时间】:2020-11-11 03:30:54
【问题描述】:

我正在使用节点的 util.promisify 尝试在辅助函数中等待 fs.readFile 结果,但第二个 readFile 从未被调用,而且我总是遇到超时错误。

根据the Mocha docsthis blog post 对promisify 实用程序函数的解释,据我所见,我正在正确使用await。

// mocha setup.js file
const { readFile } = require('fs')
const { promisify } = require('util')

module.exports = {
  readFile: promisify(readFile)
}
// test-file.js
const { assert } = require('chai')
const { readFile } = require('./setup')
const { CustomWordList, Spelling, Word } = require('../src/classes')
const nspell = require('nspell')

describe('Spelling Class', function () {
  const content = 'A colorful text that should be colorful cleaned during Spelling class instantiation! 1337'
  let dictionary
  let speller
  let obj

  before(async function () {
    this.timeout(5000)
    dictionary = await loadDictionary('en-au')
    speller = nspell(dictionary)
    obj = new Spelling(speller, content)
  })

  it('should assert object is instance of Spelling', function () {
    assert.instanceOf(obj, Spelling)
  })

  // read dictionary aff and dic files from disk and return an dictionary object
  const loadDictionary = async (filename) => {
    const dict = {}
    await readFile(`dictionaries/${filename}.dic`, 'utf8', (err, data) => {
      if (err) console.log(err)
      if (data) {
        dict.dic = data
        console.log('got dic data')
      }
    })
    await readFile(`dictionaries/${filename}.aff`, 'utf8', (err, data) => {
      if (err) console.log(err)
      if (data) {
        dict.aff = data
        console.log('got aff data')
      }
    })
    return dict
  }
})

超时错误是标准的“超时...确保调用了 done() 或确保 Promise 解决”。我注意到如果第一个 readFile 正在读取 .dic 文件,控制台将输出“got dic data”,但如果交换 readFile 操作,控制台输出是“got aff data”。

这表明出于某种原因,只有第一个 readFile 正在执行,但我不知道为什么第一个 readFile 会阻止第二个读取文件被执行(因此 return 语句无法运行)。

感谢您的宝贵时间。

【问题讨论】:

    标签: node.js async-await mocha.js fs node-promisify


    【解决方案1】:

    你做错了。在 Promisifying 之后,你的 readFile 函数将返回一个 Promise,你可以使用 async/await 来处理这个问题。如果你使用回调,那么你不应该需要承诺。

    这是您使用 async/await 编写的 loadDictionary 函数。

    const loadDictionary = async (filename) => {
        const dict = {}
    
        try {
            const data = await readFile(`dictionaries/${filename}.dic`, 'utf8');
            if (data) {
                dict.dic = data
                console.log('got dic data')
            }
        } catch (err) {
            console.log(err)
        }
    
        try {
            const data = await readFile(`dictionaries/${filename}.aff`, 'utf8');
            if (data) {
                dict.aff = data
                console.log('got aff data')
            }
        } catch (err) {
            console.log(err)
        }
    
        return dict
    }
    

    【讨论】:

    • 天哪。我真的不知道我是怎么错过的 - 像这样的时候我应该做橡皮鸭调试,这样我就可以保护自己免受脑放屁的伤害。
    • 这很正常。我们都去过那里几次:D
    猜你喜欢
    • 1970-01-01
    • 2015-12-28
    • 2018-10-31
    • 1970-01-01
    • 2013-05-24
    • 2020-10-04
    • 2019-06-07
    • 1970-01-01
    • 2012-07-06
    相关资源
    最近更新 更多