解决方案
Converting the promises into the promise factory
解决了测试运行之前出现的日志问题。我的promise.all无法解决,因为I just assumed
的NeDB数据库初始化函数遵循没有properly going through the documentation
的回调模式。再次查看文档后,我了解到不是。从promise工厂中删除回调即可解决此问题。
问题
我有一个承诺链,其中Promise
(如果已解决)将返回Promise.all
。 Promise.all
接受3个承诺。这是我的代码:
lib.init = (dir) => {
// check if the .data directory exists
return new Promise((resolve, reject) => {
if(dir) lib.baseDir = path.join(__dirname, '../', dir)
console.log('DATA LIBRARY INITIALIZATION: working directory - ', lib.baseDir)
fs.stat(lib.baseDir, (error, stats) => {
if(!error){
console.log('DATA LIBRARY INITIALIZATION: successfully retrieved file stats.')
if(!stats.isDirectory()) {
console.log('DATA LIBRARY INITIALIZATION: the base directory does not exist. Creating base directory now.')
fs.mkdir(lib.baseDir, (err) => {
if(!err) {
console.log('DATA LIBRARY INITIALIZATION: base directory created successfully.')
resolve()
} else reject('Could not create the data directory.')
})
} else resolve()
} else {
console.log('DATA LIBRARY INITIALIZATION: could not retrieve file stats. Creating base directory now.')
fs.mkdir(lib.baseDir, (err) => {
if(!err) {
console.log('DATA LIBRARY INITIALIZATION: base directory created successfully.')
resolve()
} else reject('Could not create the data directory.')
})
}
})
}).then(() => {
console.log('DATA LIBRARY INITIALIZATION: initializing databases.')
return Promise.all([loadComponents, loadShows, loadScreens])
})
}
以下是作为参数传递的三个承诺:
const loadShows = new Promise((resolve, reject) => {
// for saving profiles (set of screens designed/configured for different shows)
console.log('DATA LIBRARY INITIALIZATION: initializing SHOWS collection.')
lib.shows = new Datastore({ filename: path.join(lib.baseDir, 'shows.db'), autoload: true }, error => {
if(!error) {
console.log('DATA LIBRARY INITIALIZATION: successfully initialized SHOWS collection.')
resolve()
} else reject(`Could not load shows. Error: ${error.message}`)
})
})
const loadScreens = new Promise((resolve, reject) => {
// for saving screen settings (list of component settings)
console.log('DATA LIBRARY INITIALIZATION: initializing SCREENS collection.')
lib.screens = new Datastore({ filename: path.join(lib.baseDir, 'screens.db'), autoload: true }, error => {
if(!error) {
console.log('DATA LIBRARY INITIALIZATION: successfully initialized SCREENS collection.')
resolve()
} else reject(`Could not load screens. Error: ${error.message}`)
})
})
const loadComponents = new Promise((resolve, reject) => {
// for saving components (default settings for each component)
console.log('DATA LIBRARY INITIALIZATION: initializing COMPONENTS collection.')
lib.components = new Datastore({ filename: path.join(lib.baseDir, 'components.db'), autoload: true }, error => {
if(!error) {
console.log('DATA LIBRARY INITIALIZATION: successfully initialized COMPONENTS collection.')
resolve()
} else reject(`Could not load components. Error: ${error.message}`)
})
})
这是我的测试文件:
let chai = require('chai')
let chaiAsPromised = require('chai-as-promised')
chai.use(chaiAsPromised).should()
let _data = require('../lib/data')
describe('data library', () => {
describe('#init', () => {
it('should be able to initialize the collections without error', () => {
return _data.init('testData').should.be.fulfilled
})
})
after(function () {
// runs once after the last test in this block
// delete the testData directory and its contents
return _data.cleanup()
});
})
这是我运行mocha
时获得的日志:
yarn workspace v1.22.4
yarn run v1.22.4
$ mocha
DATA LIBRARY INITIALIZATION: initializing SHOWS collection.
DATA LIBRARY INITIALIZATION: initializing SCREENS collection.
DATA LIBRARY INITIALIZATION: initializing COMPONENTS collection.
data library
#init
DATA LIBRARY INITIALIZATION: working directory - /home/nm/projects/nightmoves/local-data/testData
DATA LIBRARY INITIALIZATION: could not retrieve file stats. Creating base directory now.
DATA LIBRARY INITIALIZATION: base directory created successfully.
DATA LIBRARY INITIALIZATION: initializing databases.
1) should be able to initialize the collections without error
DATA LIBRARY CLEANUP: removing everything in - /home/nm/projects/nightmoves/local-data/testData
DATA LIBRARY INITIALIZATION: cleanup successful.
0 passing (2s)
1 failing
1) data library
#init
should be able to initialize the collections without error:
Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. (/home/nm/projects/nightmoves/local-data/test/data.js)
at listOnTimeout (internal/timers.js:549:17)
at processTimers (internal/timers.js:492:7)
我没有得到的是为什么我什至在Mocha运行测试之前就看到Promises中的日志通过了promise.all。
答案 0 :(得分:1)
TLDR。
第二段代码为:
return (
<form
onSubmit={(e) => {
e.preventDefault(e.target.value);
addTask();
}}
>
<input
className="input-group-prepend"
value={task}
placeholder="Enter your Task"
onChange={(e) => setTask(e.target.value)}
/>
<DatePicker
// No `minDate` prop here anymore!
className="input-group-prepend"
placeholderText="Enter task date"
selected={selectedDate}
onChange={(date) => setSelectedDate(date)}
dateFormat="MMMM d, yyyy"
/>
<br />
<input className="btn btn-primary" type="submit" value="Submit" />
</form>
);
仅创建这些承诺,并在程序开始时立即执行(或至少在对模块进行const loadShows = new Promise((resolve, reject) => {
}
const loadXXX = ...
或require
编辑时执行)。
然后执行mocha和其他代码,并最终调用import
,它等待init
,并且在这个时间点上,如果它们快速完成,则可能已实现。
要解决此问题,请将功能更改为“承诺工厂”:
Promise.all(...your promises)
然后像这样使用它们:
const loadShows = () => new Promise((resolve, reject) => {
}
const loadXXX = () => ...
或在您的return Promise.all([loadShows(), ...])
方法中将其声明移至.then
处理程序。仅当您到达此代码位置时,它们才会实例化并执行。