去抖动一个方法,但继续合并和记住参数

问题描述

我有一个这样定义的方法

for pdf in files_PDF:    
    text=''
    print(pdf)
    
    pages = convert_from_path(pdf,500,poppler_path=poppler_path)
    
    for pageNum,imgBlob in enumerate(pages):
             
            
             img=cv2.imread(filename)
             d = PyTesseract.image_to_data(img,lang='spa',output_type=Output.DICT)
             n_Boxes=len(d['text'])
             for i in range(n_Boxes):
                 if int(d['conf'][i])>60:
                     (x,y,w,h)=(d['left'][i],d['top'][i],d['width'][i],d['height'][i])
                     img=cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
             
             cv2.imshow('img',img)

             
             fichero=pdf.split('/')[-1:][0][:-4]+"_data.txt"
             myFile = open(fichero,"w")
             myFile.write(text)
             myFile.close()
         

如果在 2 秒内多次调用方法,我想合并所有参数并调用它一次,例如

updateHook(obj) {
  // update the item
}
// https://www.npmjs.com/package/throttle-debounce
const update = debounce(updateHook,2000);

注意:不需要使用 debounce,要求是如果在 2 秒的时间段内多次调用方法,我只想调用具有合并参数的方法

解决方法

您可以编写自己的高阶函数,使用合并的参数调用给定的函数(参见下面示例中的 merge)。

这里最大的问题是 (IMO) merge 函数对将传递哪些参数做出了非常强的假设。
您需要自己判断是需要高度通用还是非常具体的实现。

const {debounce} = throttleDebounce;

const merge = (fn) => {
    let merge = {};

    return (obj) => {
        merge = {...merge,...obj};
        fn(merge);
    };
};

const updateHook = (obj) => {
    console.log(obj);
}

const update = merge(debounce(2000,updateHook));

update({ name: 'abc' });
update({ city: 'def' });
update({ cell: 123 });
<script src="https://unpkg.com/throttle-debounce@3.0.1/umd/index.js"></script>


另一个问题是可能需要在某个时候重置合并功能。如果这应该与去抖动超时相关,那么您可能需要一个专门的去抖动工厂

const {debounce} = throttleDebounce;

const updateHook = (obj) => {
    console.log(obj);
}

const mergedDebounce = (delay,callback) => {
    let merged = {};

    const debounced = debounce(delay,() => {
        callback(merged);
        merged = {};
    });

    return (obj) => {
        merged = {...merged,...obj};
        debounced(merged);
    };
};

const update = mergedDebounce(2000,updateHook);

update({ name: 'abc' }); // first call
update({ city: 'def' }); // second call
update({ cell: 123 }); // third call

setTimeout(() => {
    update({ foo: 42 }); // fourth call
},2500);
<script src="https://unpkg.com/throttle-debounce@3.0.1/umd/index.js"></script>

,

function updateHook(obj) {
  // update the item
  console.log('updateHook :: obj ...',obj);
}
const debounce = _.debounce;

function mergeMemoizeAndProceedWithBoundUpdateContext(data) {
  // initialize all data from the bound update context.
  const { memoizedData,proceed } = this;

  Object.assign(memoizedData,data);  // - merge into memoized data.
  proceed(memoizedData);              // - proceed with debounced function.
}
const updateData = mergeMemoizeAndProceedWithBoundUpdateContext.bind({

  memoizedData: {},// - provide the memoized data default.
  proceed: debounce(updateHook,2000) // - create the debounced proceed function.

}); // create update function with bound memoization/update context.

updateData({ name: 'abc' });
updateData({ city: 'def' });
updateData({ cell: 123 });
.as-console-wrapper { min-height: 100%!important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js"></script>

以上提供的方法对于解决当前解决的通过正确时间清除记忆数据的问题仍然有效。只需要在绑定更新上下文中提供和使用额外的 clearData 方法...

const debounce = _.debounce;

function updateHook(obj) {
  // update the item
  console.log('updateHook :: obj ...',obj);
}
const updateThreshold = 2000;

function mergeMemoizeAndProceedWithBoundUpdateContext(data) {
  const { memoizedData,clearData,data);
  proceed(memoizedData);

  clearData.call(this);
}

function clearMemoizedData() {
  this.memoizedData = {};
}
const updateData = mergeMemoizeAndProceedWithBoundUpdateContext.bind({
  memoizedData: {},clearData: debounce(clearMemoizedData,updateThreshold),proceed: debounce(updateHook,});

setTimeout(updateData,2500,{ foo: 42 });
setTimeout(updateData,6000,{ baz: 'baz' });
setTimeout(updateData,4000,{ bar: 'bar' });

updateData({ name: 'abc' });
updateData({ city: 'def' });
updateData({ cell: 123 });

setTimeout(updateData,9000,{ biz: 'biz' });
.as-console-wrapper { min-height: 100%!important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js"></script>