Reputation: 2563
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.
Upvotes: 0
Views: 1548
Reputation: 855
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
}
Upvotes: 1