记一次错:循环中调用 Promise 的 resolve 的问题

作者 : 开心源码 本文共3344个字,预计阅读时间需要9分钟 发布时间: 2022-05-12 共182人阅读

原因

最近在看方方的《造轮子》,我是直接上 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

而后马上去将 browserConsoleLogOptionscaptureConsole 里的东西加在 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。

嗯。。。还很干净。没法了,现在只有两条路

  1. 写 Issue 给这个插件作者,可能要等一会才能处理,而且不肯定能处理。
  2. 使用降级 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 里的 clientbrowserConsoleLogOptions 配置好,所以没有 log。

即便加了这个配置选项,可能当时代码原本也点问题,所以一直没发现这种”猜测写法“带来的问题。最后处理的时候的确能回想当初写这样代码的想法:“能不能循环 resolve 呢?嗯试试吧”。

总之,这是一次不错的调错经历,调完真的是身心俱疲。

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 记一次错:循环中调用 Promise 的 resolve 的问题

发表回复