I am using node's util.promisify
to try and await an fs.readFile
result inside a helper function, but the second readFile is never called and I always get a timeout error.
From what I can see I am using await correctly, according to the Mocha docs and this blog post that explains the promisify utility function.
// 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
}
})
The timeout error is the standard "timeout exceeded... ensure done() is called or ensure Promise resolves". I have noticed that the console will output "got dic data" if the first readFile is reading the .dic file, but if a swap the readFile operations, the console output is "got aff data".
This would suggest that for some reason only the first readFile is being executed, but I have no idea why the first readFile would block the second read file from being executed (and thus the return statement from ever being run).
Thanks for your time.
You're doing it wrong. After promisifying, your readFile
function will return a Promise instead, and you can use async/await to handle this. If you use callback then you shouldn't need to promisify.
Here's your loadDictionary
function written with async/await.
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
}