الفرق بين المراجعتين لصفحة: «ReactNative/timers»
إضافة الصّفحة |
لا ملخص تعديل |
||
سطر 2: | سطر 2: | ||
الموقتات جزءٌ مهم من أجزاء التطبيق. يوفّر إطار React Native مؤقتات المتصفّح. | الموقتات جزءٌ مهم من أجزاء التطبيق. يوفّر إطار React Native مؤقتات المتصفّح. | ||
==المؤقتات== | ==المؤقتات== | ||
* | * <code>setTimeout</code>، و<code>clearTimeout</code> | ||
* | * <code>setInterval</code>، و<code>clearInterval</code> | ||
* | * <code>setImmediate</code>، و<code>clearImmediate</code> | ||
* | *<code>requestAnimationFrame</code>، و<code>cancelAnimationFrame</code> | ||
لا تسلك الدالة <code>requestAnimationFrame(fn)</code> نفس سلوك الدالة <code>setTimeout(fn, 0)</code>، ستُنفَّذ الدالة الأولى بعد مسح كل الأطر، في حين ستنفّذ الدالة الثانية بأسرع وقت ممكن (أكثر من 1000x في الثانية على iPhone 5S). | لا تسلك الدالة <code>requestAnimationFrame(fn)</code> نفس سلوك الدالة <code>setTimeout(fn, 0)</code>، ستُنفَّذ الدالة الأولى بعد مسح كل الأطر، في حين ستنفّذ الدالة الثانية بأسرع وقت ممكن (أكثر من 1000x في الثانية على iPhone 5S). | ||
تُنفَّذ الدالة setImmediate في نهاية كتلة تنفيذ JavaScript الحالية، مباشرة قبل إرسال الاستجابة المجمعة (batched response) إلى اللغة الأصيلة. لاحظ أنه إذا استدعيت setImmediate داخل دالة رد نداءٍ (callback) خاصة بالدالة | تُنفَّذ الدالة <code>setImmediate</code> في نهاية كتلة تنفيذ JavaScript الحالية، مباشرة قبل إرسال الاستجابة المجمعة (batched response) إلى اللغة الأصيلة. لاحظ أنه إذا استدعيت <code>setImmediate</code> داخل دالة رد نداءٍ (callback) خاصة بالدالة <code>setImmediate</code>، فستُنفَّذ فورًا، ولن تعود إلى الجهة الأصيلة أثناء ذلك. | ||
تستخدم ميّزةُ Promise الدالةَ setImmediate كدالة لا تزامنٍ أوليّة (asynchronicity primitive). | تستخدم ميّزةُ <code>Promise</code> الدالةَ <code>setImmediate</code> كدالة لا تزامنٍ أوليّة (asynchronicity primitive). | ||
==InteractionManager== | ==<code>InteractionManager</code>== | ||
من بين الأسباب التي تجعل التطبيقات الأصلية مُتقنَةِ التصميم تبدو سَلسةً للغاية هو تجنّب إجراء العمليات المُكلّفة التي تأخذ وقتًا طويلًا أثناء التفاعلات والتحريكات. في React Native، هناك حاليا قيدٌ يتمثّل في وجود سِلسلَة تنفيذ JavaScript واحدة فقط (execution thread)، ولكن يمكنك استخدام واجهة InteractionManager للتأكد من جدولة العمليّات المُكلّفة لتشغيلها بعد اكتمال أي تفاعلات أو تحريكات. | من بين الأسباب التي تجعل التطبيقات الأصلية مُتقنَةِ التصميم تبدو سَلسةً للغاية هو تجنّب إجراء العمليات المُكلّفة التي تأخذ وقتًا طويلًا أثناء التفاعلات والتحريكات. في React Native، هناك حاليا قيدٌ يتمثّل في وجود سِلسلَة تنفيذ JavaScript واحدة فقط (execution thread)، ولكن يمكنك استخدام واجهة <code>InteractionManager</code> للتأكد من جدولة العمليّات المُكلّفة لتشغيلها بعد اكتمال أي تفاعلات أو تحريكات. | ||
يمكن للتطبيقات جدولة المهام لتشغيلها بعد | يمكن للتطبيقات جدولة المهام لتشغيلها بعد انتهاء التفاعلات بما يلي: | ||
<syntaxhighlight lang="javascript"> | <syntaxhighlight lang="javascript"> | ||
InteractionManager.runAfterInteractions(() => { | InteractionManager.runAfterInteractions(() => { | ||
سطر 25: | سطر 25: | ||
قارن هذا ببدائل الجدولة الأخرى: | قارن هذا ببدائل الجدولة الأخرى: | ||
* requestAnimationFrame(): للشيفرة التي تُحرّك عرضًا بمرور الوقت. | * <code>requestAnimationFrame()</code>: للشيفرة التي تُحرّك عرضًا بمرور الوقت. | ||
* setImmediate/setTimeout/setInterval(): تشغيل الشيفرة فيما بعد، لاحظ أن هذا قد يؤدي إلى تأخير التحريكات. | * <code>setImmediate</code>/<code>setTimeout</code>/<code>setInterval()</code>: تشغيل الشيفرة فيما بعد، لاحظ أن هذا قد يؤدي إلى تأخير التحريكات. | ||
* runAfterInteractions(): تشغيل الشيفرة فيما بعد دون تأخير التحريكات الجارية حاليًا. | * <code>runAfterInteractions()</code>: تشغيل الشيفرة فيما بعد دون تأخير التحريكات الجارية حاليًا. | ||
يَعُدُّ نظام التعامل مع اللمس لمسةً نشطةً واحدةً أو أكثرَ "تفاعلًا" وسيؤخِّر دوال ردّ نداءِ الدالةِ runAfterInteractions() حتى تنتهي جميع اللمسات أو تُلغى. | يَعُدُّ نظام التعامل مع اللمس لمسةً نشطةً واحدةً أو أكثرَ "تفاعلًا" وسيؤخِّر دوال ردّ نداءِ الدالةِ <code>runAfterInteractions()</code> حتى تنتهي جميع اللمسات أو تُلغى. | ||
تُتيح InteractionManager كذلك للتطبيقات تسجيل التحريكات عبر إنشاء "مقبضِ (handle)" تفاعلٍ عند بدء الحركة، وإزالتَه عند الانتهاء: | تُتيح <code>InteractionManager</code> كذلك للتطبيقات تسجيل التحريكات عبر إنشاء "مقبضِ (handle)" تفاعلٍ عند بدء الحركة، وإزالتَه عند الانتهاء: | ||
<syntaxhighlight lang="javascript"> | <syntaxhighlight lang="javascript"> | ||
var handle = InteractionManager.createInteractionHandle(); | var handle = InteractionManager.createInteractionHandle(); | ||
سطر 41: | سطر 41: | ||
// تُشغّل مهام الطابور عند إزالة جميع المقابض | // تُشغّل مهام الطابور عند إزالة جميع المقابض | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==TimerMixin== | ==<code>TimerMixin</code>== | ||
اكتشفنا أن السبب الأساسي للأخطاء في التطبيقات المبنيّة باستخدام React Native كان بسبب تنفيذ المؤقتات بعد فصل (unmount) المكوّن. لحل هذه المشكلة المتكررة، أضاف مطورو الإطار | اكتشفنا أن السبب الأساسي للأخطاء في التطبيقات المبنيّة باستخدام React Native كان بسبب تنفيذ المؤقتات بعد فصل (unmount) المكوّن. لحل هذه المشكلة المتكررة، أضاف مطورو الإطار مخلوط TimerMixin. إذا ضمَّنت مخلوط <code>TimerMixin</code>، فيمكنك استبدال استدعاءات <code>setTimeout(fn, 500)</code> بالاستدعاء <code>this.setTimeout(fn, 500)</code> (أضِف فقط المقطع <code>this.</code>) وسَيُنظَّفُ كل شيءٍ بشكل صحيحٍ عند فصل المكوّن. | ||
هذه المكتبة ليست جزءًا من React Native. لاستخدامها في مشروعك، سوف تحتاج إلى تثبيتها بالأمر <code>npm i react-timer-mixin --save</code> في المشروع الخاص بك. | هذه المكتبة ليست جزءًا من React Native. لاستخدامها في مشروعك، سوف تحتاج إلى تثبيتها بالأمر <code>npm i react-timer-mixin --save</code> في المشروع الخاص بك. | ||
سطر 60: | سطر 60: | ||
سيختصر هذا الكثيرَ من الوقت والجهد ويقلّل من الأخطاء، كالتوقف الفجائي الناجم عن تنفيذ دوال <code>timeout</code> بعد فصل أحد المكونات. | سيختصر هذا الكثيرَ من الوقت والجهد ويقلّل من الأخطاء، كالتوقف الفجائي الناجم عن تنفيذ دوال <code>timeout</code> بعد فصل أحد المكونات. | ||
ملاحظة: إذا كنت تستخدم أصناف ES6 لكتابة مكونات React الخاصة بك، فلا وجود [https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#mixins لواجهة برمجيّة مُضمنَة للمخاليط]. لاستخدام TimerMixin مع أصناف ES6، يُنصَح باستخدام [https://github.com/brigand/react-mixin react-mixin]. | ملاحظة: إذا كنت تستخدم أصناف ES6 لكتابة مكونات React الخاصة بك، فلا وجود [https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#mixins لواجهة برمجيّة مُضمنَة للمخاليط]. لاستخدام <code>TimerMixin</code> مع أصناف ES6، يُنصَح باستخدام [https://github.com/brigand/react-mixin react-mixin]. | ||
== مصادر == | == مصادر == | ||
* [https://facebook.github.io/react-native/docs/timers صفحة Timers في توثيق React Native الرسمي.] | * [https://facebook.github.io/react-native/docs/timers صفحة Timers في توثيق React Native الرسمي.] | ||
[[تصنيف:ReactNative]] | [[تصنيف:ReactNative]] |
مراجعة 14:04، 4 فبراير 2019
الموقتات جزءٌ مهم من أجزاء التطبيق. يوفّر إطار React Native مؤقتات المتصفّح.
المؤقتات
setTimeout
، وclearTimeout
setInterval
، وclearInterval
setImmediate
، وclearImmediate
requestAnimationFrame
، وcancelAnimationFrame
لا تسلك الدالة requestAnimationFrame(fn)
نفس سلوك الدالة setTimeout(fn, 0)
، ستُنفَّذ الدالة الأولى بعد مسح كل الأطر، في حين ستنفّذ الدالة الثانية بأسرع وقت ممكن (أكثر من 1000x في الثانية على iPhone 5S).
تُنفَّذ الدالة setImmediate
في نهاية كتلة تنفيذ JavaScript الحالية، مباشرة قبل إرسال الاستجابة المجمعة (batched response) إلى اللغة الأصيلة. لاحظ أنه إذا استدعيت setImmediate
داخل دالة رد نداءٍ (callback) خاصة بالدالة setImmediate
، فستُنفَّذ فورًا، ولن تعود إلى الجهة الأصيلة أثناء ذلك.
تستخدم ميّزةُ Promise
الدالةَ setImmediate
كدالة لا تزامنٍ أوليّة (asynchronicity primitive).
InteractionManager
من بين الأسباب التي تجعل التطبيقات الأصلية مُتقنَةِ التصميم تبدو سَلسةً للغاية هو تجنّب إجراء العمليات المُكلّفة التي تأخذ وقتًا طويلًا أثناء التفاعلات والتحريكات. في React Native، هناك حاليا قيدٌ يتمثّل في وجود سِلسلَة تنفيذ JavaScript واحدة فقط (execution thread)، ولكن يمكنك استخدام واجهة InteractionManager
للتأكد من جدولة العمليّات المُكلّفة لتشغيلها بعد اكتمال أي تفاعلات أو تحريكات.
يمكن للتطبيقات جدولة المهام لتشغيلها بعد انتهاء التفاعلات بما يلي:
InteractionManager.runAfterInteractions(() => {
// ...ضع هنا المهام المتزامنة التي تأخذ وقتا طويلا...
});
قارن هذا ببدائل الجدولة الأخرى:
requestAnimationFrame()
: للشيفرة التي تُحرّك عرضًا بمرور الوقت.setImmediate
/setTimeout
/setInterval()
: تشغيل الشيفرة فيما بعد، لاحظ أن هذا قد يؤدي إلى تأخير التحريكات.runAfterInteractions()
: تشغيل الشيفرة فيما بعد دون تأخير التحريكات الجارية حاليًا.
يَعُدُّ نظام التعامل مع اللمس لمسةً نشطةً واحدةً أو أكثرَ "تفاعلًا" وسيؤخِّر دوال ردّ نداءِ الدالةِ runAfterInteractions()
حتى تنتهي جميع اللمسات أو تُلغى.
تُتيح InteractionManager
كذلك للتطبيقات تسجيل التحريكات عبر إنشاء "مقبضِ (handle)" تفاعلٍ عند بدء الحركة، وإزالتَه عند الانتهاء:
var handle = InteractionManager.createInteractionHandle();
// تشغيل التحريك (`runAfterInteractions` ستُضاف المهام إلى طابور انتظار)
// إزالة المقبض بعد انتهاء التحريك
InteractionManager.clearInteractionHandle(handle);
// تُشغّل مهام الطابور عند إزالة جميع المقابض
TimerMixin
اكتشفنا أن السبب الأساسي للأخطاء في التطبيقات المبنيّة باستخدام React Native كان بسبب تنفيذ المؤقتات بعد فصل (unmount) المكوّن. لحل هذه المشكلة المتكررة، أضاف مطورو الإطار مخلوط TimerMixin. إذا ضمَّنت مخلوط TimerMixin
، فيمكنك استبدال استدعاءات setTimeout(fn, 500)
بالاستدعاء this.setTimeout(fn, 500)
(أضِف فقط المقطع this.
) وسَيُنظَّفُ كل شيءٍ بشكل صحيحٍ عند فصل المكوّن.
هذه المكتبة ليست جزءًا من React Native. لاستخدامها في مشروعك، سوف تحتاج إلى تثبيتها بالأمر npm i react-timer-mixin --save
في المشروع الخاص بك.
import TimerMixin from 'react-timer-mixin';
var Component = createReactClass({
mixins: [TimerMixin],
componentDidMount: function() {
this.setTimeout(() => {
console.log('I do not leak!');
}, 500);
},
});
سيختصر هذا الكثيرَ من الوقت والجهد ويقلّل من الأخطاء، كالتوقف الفجائي الناجم عن تنفيذ دوال timeout
بعد فصل أحد المكونات.
ملاحظة: إذا كنت تستخدم أصناف ES6 لكتابة مكونات React الخاصة بك، فلا وجود لواجهة برمجيّة مُضمنَة للمخاليط. لاستخدام TimerMixin
مع أصناف ES6، يُنصَح باستخدام react-mixin.