如何同时支持promise和callback回调

161 阅读1分钟

如何同时支持promise和callback回调

  • element源码中的el-form中的validate方法
  • 该方法传入callback回调,在验证参数后调用callback
  • 如果没有传入callback回调,则会返回一个promise对象,把验证参数的结果封装在promise对象中返回

我把该流程中从源码中抽离出来了,做了如下示例demo,增进理解。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>如何同时支持promise和callback回调</title>
</head>
<body>
    <script>
        // 从 element源码的 el-form的 validate 方法中提炼出如下代码 if no callback, return promise
        // 传入callback,则调用callback
        // 没有传 callback,则返回promise,  
        function validate(callback) {

            // ....省略验证代码
            
            let promise;
            if(typeof callback !== 'function' && window.Promise) {
                promise = new Promise((resolve, reject) => { // 定义promise对象
                // resolve("Hattori");
                    callback = function(valid, invalidFields) {
                        valid ? resolve(valid) : reject(invalidFields);
                    };
                 });
            }

            console.log("promise前==",promise); // promise前== Promise {<pending>}
            callback(true);  
            // callback(false,'用户名不能为空');  
            /* 
            1. 在promise情况下,调了callback方法,
            2. 如果传的flag为true,会走resolve方法, 此时就将promise对象的状态置成了 fulfilled
            3. 如果传的flag是false,则走reject方法,此时就将promise对象的状态置成了 Promise {<rejected>: '用户名不能为空'}
            */
            console.log("promise后==",promise); // promise后== Promise {<fulfilled>: true}

            if(promise) {
                return promise
            }
        }

       // callback方式
        validate((valid,invalidFields) => {
            if(valid) {
                alert('valid success')
            }else {
                alert(invalidFields)
            }
        })

        // promise方式
        validate().then(valid => {
            if(valid) {
                alert('valid success')
            }
        }).catch(invalidFields => {
            alert(invalidFields)
        })
    </script>
</body>
</html>