javascript模块化文件方法的相互调用

近日再做一些模块化相关的工作,遇到这样一个问题

模块A负责处理数据层面的一些逻辑,模块B负责处理视图层面的一些逻辑

现在A要调用B的方法,做一些视图逻辑的处理,之后要再B调用回A的方法,处理一些数据逻辑,最后再回到B,继续处理视图逻辑,听起来很绕对吧!是的!

一般碰到这种调用来又调用去的东西,我们很容易想到就是import,管他三七二十一,我直接导,导不出来再想办法!

但是如今这个场景,兄弟们如果直接导,会导致模块间的循环引用,代码会报错,那怎么办?

我就想到了写一个CallBack回调,按照事情发生的顺序,一步一步执行下来,下面是我的思路

  1. A模块调用B模块的方法,把整个事件的主导交给B,并把回调方法交给B
  2. B先处理视图逻辑,处理的差不多了,调用A给的回调(改为同步)
  3. 等到A的回调做完了,回来继续执行B

听起来还是很绕,不如直接看代码

【模块A】

let params = { multiple, small, big }

//scanConfig为B模块引入的对象
//renderScanPic为A模块写的回调方法

that.scanConfig.scanUploadViewBuilder( params, (data)=>that.renderScanPic(data) )






renderScanPic(data){
        return new Promise(async (resolve,reject)=>{
            for(const o of data){
                let result = o
    
                this.dataAndView_addData('img',result)
    
                const config =  {
                    src: o.thumb_url, 
                    notes: null, 
                    fileName, 
                    status:0
                }
                await this.renderSinglePic(config)
            }
            resolve(true)
        })
        

    }

【模块B】

//模块B scanConfig提供的方法 scanUploadBuilder
//可以看出来这里确实是一些视图层的代码
//同时,接收两个参数,也是A传过来的,一个是一些普通参数,一个是A的回调

scanUploadViewBuilder(params, getDataAndRenderCallBack) {
        const that = this
        const { multiple, small, big } = {...params}
        let timestamp = new Date().getTime()
        params = `?multiple=${multiple}&small=[${small}]&big=[${big}]&timestamp=${timestamp}`
        const H5_upload_src = that.uploadUrl + params

        let QRCodeContainer = $(`<div class="QRCode-container QRCodeContainer"></div>`)
        let QRCodeContent = $(`<div class="QRCodeContent"></div>`)
        let QRCodeContentTop = $(`<div class="phoneUploadStyle QRCodeContentTop"></div>`)
        let QRCodeContentBottom = $(`<div class="QRCodeContentBottom">
                                                <div style="margin-top:-10px;" id="qrCode"></div>
                                                <div class="QRCodeContentBottomTips">传图期间请勿关闭此二维码</div>
                                            </div>`)
        let QRCodeContentTopText = '<span>手机扫码传图片(不支持文件上传)</span>'
        let QRCodeContentTopIcon = $(`<svg 
                                                t="1687167723133" 
                                                viewBox="0 0 1024 1024" 
                                                width="22" 
                                                height="22" 
                                                style="float: right;cursor: pointer;">
                                                <path d="M860.4 64H163.6c-50.9 0-92.2 41.3-92.2 92.2v711.5c0 50.9 41.3 92.2 92.2 92.2h696.8c50.9 0 92.2-41.3 92.2-92.2V156.2c0-50.9-41.3-92.2-92.2-92.2zM721.9 642.1c24.4 24.4 24.4 64 0 88.4-24.4 24.4-64 24.4-88.4 0L512 609 390.5 730.5c-24.4 24.4-64 24.4-88.4 0-24.4-24.4-24.4-64 0-88.4l121.5-121.5-121.4-121.5c-24.4-24.4-24.4-64 0-88.4 24.4-24.4 64-24.4 88.4 0L512 432.2l121.5-121.5c24.4-24.4 64-24.4 88.4 0 24.4 24.4 24.4 64 0 88.4L600.4 520.6l121.5 121.5z" fill="#626262"></path>
                                            </svg>`)
        QRCodeContentTopIcon.on('click', that.removeQRCodeContainer_upload.bind(this))
        $('body').append(
            QRCodeContainer.append(
                QRCodeContent.append(
                    QRCodeContentTop.append(
                        QRCodeContentTopText, QRCodeContentTopIcon
                    )
                    , QRCodeContentBottom
                )
            )
        )
        $('#qrCode').qrcode(H5_upload_src)

/呐呐呐
/这里我又调用了B的另一个方法,同时把A的回调拿过去用了
/
        that.timePolling_upload(timestamp, getDataAndRenderCallBack)
    }

    removeQRCodeContainer_upload() {
        $('.QRCode-container').remove()
        clearInterval(this.clear)
    }

//没错,就是它最终拿到A的回调
    timePolling_upload(timestamp, getDataAndRenderCallBack){
        const that = this
        let accpetData = []
        this.clear = setInterval(() => {
            $.ajax({
                type: 'get',
                dataType: 'json',
                url: that.getUrl + '?get_image=1&unique_id=' + timestamp,
                async success(res) {
                    if (res.code == 1) {
                        if(JSON.stringify(accpetData) != JSON.stringify(res.data)){
                            accpetData = res.data
                        }else{

                            这里是使用A回调的地方,绕了一大圈 终于到了
                            
                            
                            const resultData = that.transformFormatData(accpetData)
                            //然后就等,getDataAndRenderCallBack得return一个promise

                            await getDataAndRenderCallBack(resultData)

                            //等完了,继续执行视图
                            that.removeQRCodeContainer_upload()
                        }
                    }
                }
            })
        }, 5000)
    }

模块B比较啰嗦,大家看我写注释的地方就好了,那么,这篇文章的精髓在哪里,我个人认为,是在A模块那里,(data)=>that.renderScanPic(data),就这里,相当的精髓

一开始我的写法其实不是这样的,我直接that.renderScanPic,没加箭头函数,(好吧一开始甚至还写成that.renderScanPic(data),但这样不行,因为给了括号,他会认为我需要在此时执行这个方法,并把返回值传给模块B,这样是不对滴)。

那么为什么突然要加个箭头函数呢?如果不加,我的renderScanPic会丢失this的指向,我在这个A模块的方法中把这个this打印出来,他既不指向A,也不指向B,大家猜猜,他会指向什么,他居然指向undefined,之前我也写过一篇关于this指向的文章,但像当前这种绕来绕去的场景,确实也是没有考虑到。

那么又继续到我的推测环节了,为什么A调用B调用A的回调,this的指向会变成undefined?

首先,依照我的推理,this至少也得指向B吧?因为B调用A的回调,也就是A的方法会进到B里面,那么这时候的作用域,按道理得是B,但目前是undefiend,只能让懂得兄弟评论区解答一下了,后续我也会再补充一下这个问题的答案(我会亲自去尝试一下),暂且就在这里收尾吧!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值