记一次错:循环中调用 Promise 的 resolve 的问题
原因
最近在看方方的《造轮子》,我是直接上 vue-cli 3 的,所以在配置上真的下了很大功夫。今天就出现了在循环里调用 resolve 函数的问题。
先说说我的配置吧,我是使用 vue-cli 3 + vue-cli-plugin-unit-karma 插件来配置的 Karma 的。
vue.config.js
vue-cli 3 是不需要 webpack.config.js 的,所以要将配置 Karam 要使用 vue-cli-plugin-unit-karma 插件,这也是官方推荐的方法,而且这个插件是和 vue-cli-service 配合的连 package.json 里的 test 都不用改,直接 vue-cli-service test:unit
一波带走。这里面我还使用了全局 Sass 文件。
const karmaConfig = require('./karma.config')module.exports = { publicPath: process.env.NODE_ENV === 'production' ? '/overwatch-ui/' : '/', css: { loaderOptions: { sass: { // @ -> /src data: ` @import "@/assets/styles/global.scss"; @import "@/assets/styles/reset.scss"; ` } } }, pluginOptions: { karma: { expressServer: undefined, karmaConfig: karmaConfig } }}
karam.config.js
注意,这不是官方所用的那种 karam.config.js 文件,我的文件只是返回一个对象,不想在 vue.config.js 里写太长了而已。
module.exports = { basePath: '', frameworks: ['mocha', 'chai', 'sinon-chai'], client: { chai: { includeStack: true }, }, files: [ 'tests/**/*.spec.js', 'tests/**/*.spec.ts', ], reporters: ['progress'], port: 9876, colors: true, autoWatch: true, browsers: ['ChromeHeadless'], concurrency: Infinity,}
Input.spec.js
先定义一下 testProperty
函数,由于我理想的情况是多种值都要测,所以应该循环一个数组,对数组里每个值都做一次测试(就是这个代码坑了,用回调好好的,自己非得装B用 Promise 来玩)。
function testProperty(values) { return new Promise((resolve, reject) => { values.forEach((value) => resolve(value)) })}
这里我就不写那么多代码啦,大家看到这就意会一下就行了。
describe('events', ()=> { it('can be handled', () => { const events = ['click', 'change', 'input'] const eventHandler = sinon.stub() testProperty(events) .then((eventName) => { console.log(eventName) const InputVue = shallowMount(Input, { listeners: { [`${eventName}`]: eventHandler } }) InputVue.find('input').trigger(eventName) expect(eventHandler.called).to.equal(true) }) })})
说完上面的基本配置,就说说今天的采坑记吧。
没有 Log?
当我运行 yarn run test
的时候,发现 Karma 跑通了,Yes,第一波 Vue + Karam 配置成功!
哎不对,我的 console.log(eventName)
怎样没了?第一反应是 Karam 没有配置好,由于测试是归 Karma 管的。而后 Google 了一下,找到了 Karam runner 里 Karam-Mocha 里的 Issue
而后马上去将 browserConsoleLogOptions
和 captureConsole
里的东西加在 karam.config.js
里。再次运行,Boom,还是不行,什么都没有打印。
config 是谁,它在哪?
尽管这个人很多赞,但是毕竟是个人说辞,不太可靠,他既然说到了 Karma 的配置,那么官方文档一定会有说呀。Go,下一步 Karam 官方文档。果然我找到一个配置:
说是在 karam.config.js 里设置 config.LOG_INFO
的,像这样:
module.exports = function(config) { config.set({ logLevel: config.LOG_INFO, });};
但是,这种是不是 vue cli 3 的写法,这是 vue cli + webpack.config.js 的写法呀。我了个去,这么写 config 都不知道从哪来,常量 LOG_INFO
一定是 undefined
。
哎,尽管我不能配置 logLevel: config.LOG_INFO
,但是我可以用命令行呀,所以马上去 package.json 里改脚本命令:
"test": "vue-cli-service test:unit --log-level debug"
开 iTerm2,秒写命令:
yarn run test
但是还是没 log,当时心态已经到崩溃的边缘了。
484你这个 0.5 版本的插件不行啊
现在头号嫌疑犯就是这个插件了,由于 --log-level debug
写在 vue-cli-service
后面,应该是要 vue-cli-service
结合使用的,而这个插件号称自己和 vue-cli-service 完美结合,一看版本才 0.5 想:是不是你这个弱智没写好插件就四处装B了。又去看了这个插件的 Issue。
嗯。。。还很干净。没法了,现在只有两条路
- 写 Issue 给这个插件作者,可能要等一会才能处理,而且不肯定能处理。
- 使用降级 vue-cli,使用 vue-cli 和 webpack.config.js 结合的老方法,肯定能行,但是麻烦。
两个方法都很难受,所以我选择了第三种方法:在别的地方打 log,是不是真的别的地方都不能打 log 了。所以我在 testProperty
里加了句:
function testProperty(values) { return new Promise((resolve, reject) => { console.log(values) values.forEach((value) => resolve(value)) })}
结果竟然有 log 了!看来上面的方法一律作废了,别的地方能 log 说明配置完全正确。
循环 resolve 害死人啊
其实我一开始写的 testProperty
是这样的:
function testProperty(values, callback) { values.forEach(callback)}
我想了想,是不是有点 low 啊,这样封装如同都没什么意义,所以使用了 Promise 写法。而这种写法只能在循环里调用 resolve(value)
才能将数组元素传入回调里。后面自己再试了试,then()
完了之后只会调用一次 resolve(value)
,而不会在循环里屡次调用,我的这种写法纯粹属性猜测去写,所以导致看了半天的 Issue 和 StackOverflow 才慢慢处理了这个问题。
总结
其实我的循环调用 resolve 是可以打出一个 log 的,由于会调用一次,但是前期的确没有将 karam.config.js 里的 client
和 browserConsoleLogOptions
配置好,所以没有 log。
即便加了这个配置选项,可能当时代码原本也点问题,所以一直没发现这种”猜测写法“带来的问题。最后处理的时候的确能回想当初写这样代码的想法:“能不能循环 resolve 呢?嗯试试吧”。
总之,这是一次不错的调错经历,调完真的是身心俱疲。
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 记一次错:循环中调用 Promise 的 resolve 的问题