利用 Promise 进行验证的一些实践

一、业务场景

  众所周知,在客户端中,表单是一个相当重要的内容。随着技术的发展,在提交表单数据的时候,某些表单验证环节会放在前端进行。因此,我们无可避免的要写一堆 if 来处理,同时大多数的时候,如果需要提醒某些错误信息时,需要加入 else 以及 else if 来控制,当然也可以使用 retrun。不过随着表单越来越复杂,表单项之间的关联越来越复杂的时候,看着一屏都放不下的判断嵌套,心中是万千草泥马奔腾而过。

 

二、与 promise 的结合

  promise 的出现主要是为了解决复杂的回调嵌套,因此在这里也是借用了这个特点,解决我们的痛点。代码见下:

function validate (scb = () => {}, ecb= () => {}) {
    return new Promise((resolve, reject) => {
        // area 1
        if (...) reject('error message 1');
        if (...) reject('error message 2');
        if (...) reject('error message 3');
        if (...) reject('error message 4');
        ...

        // area 2
        resolve();
    }).then((result) => {
        // area 3
        scb();
    }).catch((err) => {
        // area 4
        console.error(err);
        yourToastFunc(err);
        ecb();
    });
}

 

  代码中 area 1 是主要的逻辑判断区, area 2 执行时表示 area 1 中的验证全通过, area 3 则是全通过之后的成功回调函数(scb => successCallback 缩写, ecb 同),相反 area 4 是未通过之后的处理区域。这段主要是利用 reject 阻断后续代码执行的特性,直接捕获当前错误的地方从而确定是何条件未通过以及对应的提示语,从而提高后续的定位速度。

 

三、一些思考

  这段代码本身并没有改变多少思考范式,本身也依赖 area 1 中的逻辑判断语句的编写,优点是在条件判断的下一步做了一点统合,不必再每一个分支内重复地写 return or toast。简单而言,就是用 reject 尽可能代替了 else。

  同时,因为 area 1 中的需要编写判断的原因,这里也是耦合度较高的地方,从这方面讲,是可以后续改进的地方。不过,需要掌握好平衡。

  当然,后续升级的方向也可以是像 element-ui 的 form 那样,传入对象,传入自定义的验证器等等,同时这里又要考虑作用域(用于某些表单联动时上下文中的变量获取)等等问题。

  总之,没有完美的解决方案。事物的发展是螺旋式前进的,实事求是,根据不同的实际抽象出不同的核心需求,然后选择才能总结出相应的最合理的解决办法。

 

四、对于 if else 的优化

1. 彻底消除if else, 让你的代码看起来更优雅

posted @ 2020-10-09 13:21  shiweiqianju  阅读(540)  评论(0编辑  收藏  举报