إذا استخدمت _.debounce () لإنشاء دالة debounce ثم استدعيتها 3 مرات متتالية مع 3 مجموعات مختلفة من الوسيطات ، ثم (اعتبارًا من الإصدار 1.1.7) سيتم استدعاء وظيفة الحمولة المغلفة أخيرًا باستخدام الوسيطات المحددة بواسطة الاستدعاء الثالث - هذا هو يتم تجاهل الوسيطتين الأولى والثانية.
على الرغم من أن هذا غالبًا ما يكون صالحًا (وما يفعله عادةً إلغاء المفاتيح ، ومن ثم فهو افتراضي معقول) أجد نفسي أرغب في استخدام debounce لتجميع الحجج ، على سبيل المثال لدي مكالمة AJAX يمكنها الحصول على مفاتيح متعددة في وقت واحد ، لذلك أستخدم debounce للتخزين المؤقت مفاتيح التشغيل لمدة ثانية ثم إصدار طلب مشترك.
لذا فإن اقتراحي هو أن debounce يأخذ الوسيطة الثالثة "المدمجة" الاختيارية التي سيتم استدعاؤها بـ 2 args ،
إذا لم يتم تمرير أي قيمة للمعامل المدمج ، فإن الدمج الافتراضي يحافظ على السلوك الحالي
function(acc, newargs) { return newargs; }
ولكن يمكنك أيضًا أن تقرر استخدام المجموعة الأولى من الوسائط
function(acc, newargs) { return acc || newargs; }
أو ما أريد القيام به هو ببساطة إلحاق جميع الحجج
function(acc,newargs) { return (acc || []).concat(newargs); }
وبالطبع قد يرغب الآخرون في فعل شيء أفضل
قد يتطلب ذلك التغيير التالي لوظيفة الحد الداخلي
// Internal function used to implement `_.throttle` and `_.debounce`.
var limit = function(func, wait, debounce, combine) {
var timeout, allargs;
return function() {
var context = this;
allargs = combine(allargs, slice.call(arguments,0))
var throttler = function() {
timeout = null;
var args = allargs;
allargs = undefined;
func.apply(context, args);
};
if (debounce) clearTimeout(timeout);
if (debounce || !timeout) timeout = setTimeout(throttler, wait);
};
};
ثم تغيير للإنزال للقبول وتمرير الوسيطة الجديدة بالقيمة الافتراضية إذا لم يتم تحديدها.
_.debounce = function(func, wait, combine) {
return limit(func, wait, true, combine || function(acc,newargs) { return newargs; });
};
تستخدم وظيفة الخانق المقابلة حاليًا المجموعة الأولى من الوسائط وحدها (يتجاهل الخانق بشكل فعال المكالمات التي تحدث في غضون مللي ثانية من المكالمة الأولى ويستخدم مجموعة الاستدعاء الأولى من args ، ويتجاهل debounce بشكل فعال الكل ما عدا المكالمة الأخيرة في تسلسل يحدث خلال فترة الانتظار من بعضها البعض) ، لذلك أقترح ما يلي للحفاظ مرة أخرى على السلوك الافتراضي الحالي
_.throttle = function(func, wait, combine) {
return limit(func, wait, false, combine || function(acc,newargs) { return acc || newargs; });
};
قد يبدو هذا هو الطريقة الأسهل والأكثر عمومية لتحقيق هذه الوظيفة بدون أغلفة مفرطة للحفاظ على قوائم الوسائط ، ولكن سأكون مهتمًا بمعرفة ما إذا كانت هناك طريقة سهلة لتحقيق ذلك دون تغيير الشرطة السفلية.
بالتعليق على اقتراحي الخاص ، يجب أن تحدد دعوة الدمج () نفس سياق وظيفة الحمولة ، وبالتالي
allargs = combine.apply(this, [allargs, slice.call(arguments,0)])
في حالة احتياج الوسيطات للوصول إلى كائن السياق ....
الآن يجب أن تكون ثابتة على الماجستير. يجب أن يعرض throttle
السلوك الصحيح حيث يستخدم دائمًا أحدث نسخة من الوسائط الخاصة بك ، ويتم إطلاقه مرة واحدة على الفور ، وكل N
ثانية بعد ذلك ... ويعيد تعيين نفسه N
ثانية بعد ذلك حدث آخر زناد زائدة.
أعتقد أن تعليقك الوثيق ينطبق على مشكلة أخرى (ربما رقم 170) ، حيث أن المشكلة التي أثارها هذا الطلب لا تزال سارية على الماجستير.
لا تزال هناك طريقة سهلة لتجميع الحجج المتراكمة من المكالمات التي يتم دمجها ، وما زلت أعتقد أنها إضافة اختيارية مفيدة تترك السلوك الافتراضي دون تغيير عندما لا يتم تحديد وسيطة الجمع الاختيارية.
آه ، أنت على حق. تعد الوسائط المتراكمة خارج نطاق الشرطة السفلية - لا تتردد في تخزين بياناتك المتراكمة في مكان جيد خارج الدالتين _.throttle
و _.debounce
.
هذا أمر مؤسف ، أعتبر أن debounce هو نوع من أضعاف اليسار (تقليل) على مكالمات متعددة مع مهلة ومن ثم المجمع ... لكنها مكالمتك :)
حسنًا ، ليس للاستمرار في الضجيج ، ولكن في حالة نظر أي شخص إلى هذا في وقت ما لاحقًا وتساءل عن كيفية القيام بالمثل ، فقد اكتشفت أن هذا كان حول أنظف طريقة دون تعديل التنبيه نفسه (أقوم بإضافته إلى الكائن ، وقد لا يفضل الآخرون ذلك) ل)
_.mixin({
debounceReduce: function(func, wait, combine) {
var allargs,
context,
wrapper = _.debounce(function() {
var args = allargs;
allargs = undefined;
func.apply(context, args);
}, wait);
return function() {
context = this;
allargs = combine.apply(context, [allargs, Array.prototype.slice.call(arguments,0)]);
wrapper();
};
}
})
هذا يعطي دالة مرفوضة والتي يتم تقليل وسيطاتها بواسطة وظيفة الجمع ، على سبيل المثال ،
delayLog = _.debounceReduce(function() { console.log(arguments); }, 5000,
function(acc,args) { return (acc || []).concat(args); });
delayLog(3,4);
delayLog(7,8,9);
ستستدعي بعد ثوانٍ console.log مع المصفوفة [3،4،7،8،9]
schmerg - يبدو هذا مفيدًا للغاية. هل أنت على استعداد لترخيص هذا الرمز بموجب ترخيص MIT؟ (ستكفي "نعم"!)
markjaquith شيء أكيد - نعم. سعيد ل...
إذا أتى أي شخص وأراد إصدار js الحديث المحدث / المعلق لما سبق:
_.mixin({
debounceReduce(func, wait, combine) {
let allArgs; // accumulator for args across calls
// normally-debounced fn that we will call later with the accumulated args
const wrapper = _.debounce(() => func(allArgs), wait);
// what we actually return is this function which will really just add the new args to
// allArgs using the combine fn
return (...args) => {
allArgs = combine(allArgs, [...args]);
wrapper();
};
},
});
kmannislands مرحبًا ، لم يتم إعادة تعيين نسختك allArgs
داخل wrapper()
، لذا فإن المكالمات اللاحقة إلى func()
تحصل على دفعات تاريخية من args بالإضافة إلى الدُفعة الحالية.
ألا يجب أن يكون:
const wrapper = _.debounce(() => {
const args = allArgs;
allArgs = undefined;
func(args);
}, wait);
تضمين التغريدة
يختلف أيضًا func( args )
عن الإصدار الأصلي الذي يستخدم func.apply(context, args);
.
بالنسبة للأول ، يتم استخدام args
كما هو الحال في الهدف func()
، بينما في الأحدث _ (الكود الأصلي) _ تحتاج إلى استخدام إما arguments
في وظيفة عادية أو ( ...args )
في دالة es6 للسهم السميك.
التعليق الأكثر فائدة
حسنًا ، ليس للاستمرار في الضجيج ، ولكن في حالة نظر أي شخص إلى هذا في وقت ما لاحقًا وتساءل عن كيفية القيام بالمثل ، فقد اكتشفت أن هذا كان حول أنظف طريقة دون تعديل التنبيه نفسه (أقوم بإضافته إلى الكائن ، وقد لا يفضل الآخرون ذلك) ل)
هذا يعطي دالة مرفوضة والتي يتم تقليل وسيطاتها بواسطة وظيفة الجمع ، على سبيل المثال ،
ستستدعي بعد ثوانٍ console.log مع المصفوفة [3،4،7،8،9]