Skip to content

Commit 1971431

Browse files
authored
Merge pull request #70 from AhmedIbrahimGalal/callbacks
callbacks
2 parents e3e0578 + 1422d63 commit 1971431

2 files changed

Lines changed: 78 additions & 77 deletions

File tree

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11

2-
# Animated circle with callback
2+
# دائرة متحركة بواسطة ال callback
33

4-
In the task <info:task/animate-circle> an animated growing circle is shown.
4+
في المهمة <info:task/animate-circle> تظهر دائرة متنامية متنامية.
55

6-
Now let's say we need not just a circle, but to show a message inside it. The message should appear *after* the animation is complete (the circle is fully grown), otherwise it would look ugly.
6+
الآن دعنا نقول أننا لسنا بحاجة فقط إلى دائرة ، ولكن لإظهار رسالة بداخلها. يجب أن تظهر الرسالة *بعد* اكتمال الرسم المتحرك (الدائرة كاملة) ، وإلا ستبدو قبيحة.
77

8-
In the solution of the task, the function `showCircle(cx, cy, radius)` draws the circle, but gives no way to track when it's ready.
8+
في حل المهمة ، ترسم هذه الدالة `showCircle(cx, cy, radius)` دائرة, لكنها لا تعطي أي وسيلة للتتبع عندما تكون جاهزة.
99

10-
Add a callback argument: `showCircle(cx, cy, radius, callback)` to be called when the animation is complete. The `callback` should receive the circle `<div>` as an argument.
10+
أضف وسيطة ال callback: `showCircle(cx, cy, radius, callback)` ليتم أستدعاءها عندما الحركه تكتمل. الدالة `callback` يجب أن تستقبل الدائرة `<div>` كوسيط.
1111

12-
Here's the example:
12+
إليك المثال:
1313

1414
```js
1515
showCircle(150, 150, 100, div => {
@@ -18,8 +18,8 @@ showCircle(150, 150, 100, div => {
1818
});
1919
```
2020

21-
Demo:
21+
الناتج:
2222

2323
[iframe src="solution" height=260]
2424

25-
Take the solution of the task <info:task/animate-circle> as the base.
25+
خذ حل المهمة <info:task/animate-circle> كقاعدة.

1-js/11-async/01-callbacks/article.md

Lines changed: 70 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,68 @@
11

22

3-
# Introduction: callbacks
3+
# مقدمة: callbacks
44

5-
```warn header="We use browser methods in examples here"
6-
To demonstrate the use of callbacks, promises and other abstract concepts, we'll be using some browser methods: specifically, loading scripts and performing simple document manipulations.
5+
```warn header="نستخدم طرق المتصفح في الأمثلة هنا"
6+
لتوضيح استخدام الاسترجاعات والوعود والمفاهيم المجردة الأخرى ، سنستخدم بعض طرق المتصفح: على وجه التحديد ، تحميل البرامج النصية وأداء التلاعب بالمستندات البسيطة.
77
8-
If you're not familiar with these methods, and their usage in the examples is confusing, you may want to read a few chapters from the [next part](/document) of the tutorial.
8+
إذا لم تكن على دراية بهذه الطرق ، وكان استخدامها في الأمثلة مربكًا ، فقد ترغب في قراءة بعض الفصول من [الجزء التالي](/document) من الدورة التعليمية.
99
10-
Although, we'll try to make things clear anyway. There won't be anything really complex browser-wise.
10+
على الرغم من أننا سنحاول توضيح الأمور على أي حال. لن يكون هناك أي شيء معقد بالفعل في المتصفح.
1111
```
1212

13-
Many functions are provided by JavaScript host environments that allow you to schedule *asynchronous* actions. In other words, actions that we initiate now, but they finish later.
13+
يتم توفير العديد من الوظائف من خلال بيئات استضافة JavaScript التي تسمح لك بجدولة الاحداث *الغير متزامنة*. بعبارة أخرى ، الإجراءات التي نبدأها الآن ، لكنها تنتهي لاحقًا.
1414

15-
For instance, one such function is the `setTimeout` function.
15+
علي سبيل المثال, داله واحده مثل دالة ال `setTimeout`.
1616

17-
There are other real-world examples of asynchronous actions, e.g. loading scripts and modules (we'll cover them in later chapters).
17+
هناك أمثلة أخرى على أرض الواقع من الإجراءات غير المتزامنة ، مثل تحميل البرامج النصية والوحدات (سنغطيها في الفصول اللاحقة).
1818

19-
Take a look at the function `loadScript(src)`, that loads a script with the given `src`:
19+
ألق نظرة علي الدالة `loadScript(src)`, والتي تقوم بتحميل برنامج نصي عند أعطاءها مصدر البرنامج `src`:
2020

2121
```js
2222
function loadScript(src) {
23-
// creates a <script> tag and append it to the page
24-
// this causes the script with given src to start loading and run when complete
23+
// أنشئ العنصر <script> و قم بأضافته الي الصفحة
24+
// هذا الذي يفعله البرنامج النصي عند أعطاءه ال src لكي يبدأ تحميل ومن ثم يشغل البرنامج عند الاكتمال
2525
let script = document.createElement('script');
2626
script.src = src;
2727
document.head.append(script);
2828
}
2929
```
3030

31-
It appends to the document the new, dynamically created, tag `<script src="…">` with given `src`. The browser automatically starts loading it and executes when complete.
31+
يتم إلحاق المستند الجديد ، الذي تم إنشاؤه ديناميكيًا ، العنصر `<script src="…">` نعطي له مصدر البرنامج النصي `src`. المتصفح بتحميله تلقائياً و يقوم بتشغيله عند اكتمال التحميل.
3232

33-
We can use this function like this:
33+
نحن نستطيع أستخدام هذه الدالة كما موضح بالأسفل:
3434

3535
```js
36-
// load and execute the script at the given path
36+
// تحميل وتنفيذ البرنامج النصي في المسار المحدد
3737
loadScript('/my/script.js');
3838
```
3939

40-
The script is executed "asynchronously", as it starts loading now, but runs later, when the function has already finished.
40+
يتم تنفيذ البرنامج النصي "بشكل غير متزامن" ، حيث يبدأ التحميل الآن ، ولكن يتم تشغيله لاحقًا ، عندما تنتهي الوظيفة بالفعل.
4141

42-
If there's any code below `loadScript(…)`, it doesn't wait until the script loading finishes.
42+
اذا كان هناك أي كود أسفل ال `loadScript(…)`, فأنه لن ينتظر حتي أنتهاء تحميل الملف النصي.
4343

4444
```js
4545
loadScript('/my/script.js');
46-
// the code below loadScript
47-
// doesn't wait for the script loading to finish
46+
// الكود أسفل ال loadScript
47+
// لا ينتظر تحميل البرنامج النصي حتى ينتهي
4848
// ...
4949
```
5050

51-
Let's say we need to use the new script as soon as it loads. It declares new functions, and we want to run them.
51+
لنفترض أننا بحاجة إلى استخدام البرنامج النصي الجديد بمجرد تحميله. تعلن وظائف جديدة ، ونريد تشغيلها.
5252

53-
But if we do that immediately after the `loadScript(…)` call, that wouldn't work:
53+
ولكن أذا فعلنا ذلك مباشرةً بعد أستدعاء الدالة `loadScript(…)`, هذا لن يعمل:
5454

5555
```js
56-
loadScript('/my/script.js'); // the script has "function newFunction() {…}"
56+
loadScript('/my/script.js'); // البرنامج النصي يمتلك "function newFunction() {…}"
5757

5858
*!*
59-
newFunction(); // no such function!
59+
newFunction(); // لا يوجد مثل هذه الوظيفة!
6060
*/!*
6161
```
6262

63-
Naturally, the browser probably didn't have time to load the script. As of now, the `loadScript` function doesn't provide a way to track the load completion. The script loads and eventually runs, that's all. But we'd like to know when it happens, to use new functions and variables from that script.
63+
بطبيعة الحال ، ربما لم يكن لدى المتصفح وقت لتحميل البرنامج النصي. اعتبارا من الآن، الدالة `loadScript` لا توفر الوظيفة طريقة لتتبع إكمال التحميل. يتم تحميل البرنامج النصي وتشغيله في النهاية ، هذا كل ما في الأمر. ولكن نود أن نعرف متى يحدث ذلك ، لاستخدام وظائف ومتغيرات جديدة من هذا البرنامج النصي.
6464

65-
Let's add a `callback` function as a second argument to `loadScript` that should execute when the script loads:
65+
دعنا نضيف وظيفة `callback` كوسيطة ثانية إلى` loadScript` التي يجب تنفيذها عند تحميل البرنامج النصي:
6666

6767
```js
6868
function loadScript(src, *!*callback*/!*) {
@@ -77,19 +77,19 @@ function loadScript(src, *!*callback*/!*) {
7777
}
7878
```
7979

80-
Now if we want to call new functions from the script, we should write that in the callback:
80+
الآن إذا أردنا استدعاء وظائف جديدة من البرنامج النصي ، يجب أن نكتب ذلك في رد الاتصال:
8181

8282
```js
8383
loadScript('/my/script.js', function() {
84-
// the callback runs after the script is loaded
85-
newFunction(); // so now it works
84+
// يعمل دالة ال callback بعد تحميل البرنامج النصي
85+
newFunction(); // حتى الآن يعمل
8686
...
8787
});
8888
```
8989

90-
That's the idea: the second argument is a function (usually anonymous) that runs when the action is completed.
90+
هذه هي الفكرة: الوسيطة الثانية هي وظيفة (عادة ما تكون مجهولة المصدر) يتم تشغيلها عند اكتمال الإجراء.
9191

92-
Here's a runnable example with a real script:
92+
إليك مثال قابل للتشغيل مع نص حقيقي:
9393

9494
```js run
9595
function loadScript(src, callback) {
@@ -102,20 +102,21 @@ function loadScript(src, callback) {
102102
*!*
103103
loadScript('https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.2.0/lodash.js', script => {
104104
alert(`Cool, the script ${script.src} is loaded`);
105-
alert( _ ); // function declared in the loaded script
105+
alert( _ ); // دالة معلن عنها في البرنامج النصي المحمل
106106
});
107107
*/!*
108108
```
109109

110-
That's called a "callback-based" style of asynchronous programming. A function that does something asynchronously should provide a `callback` argument where we put the function to run after it's complete.
110+
وهذا ما يسمى نمط "قائم على الاسترجاع" للبرمجة غير المتزامنة. يجب أن توفر الدالة التي تفعل شيئًا بشكل غير متزامن وسيطة `callback` حيث نضع الوظيفة قيد التشغيل بعد اكتمالها.
111111

112-
Here we did it in `loadScript`, but of course it's a general approach.
113112

114-
## Callback in callback
113+
هنا فعلنا ذلك `loadScript`, ولكن بالطبع هذا نهج عام.
115114

116-
How can we load two scripts sequentially: the first one, and then the second one after it?
115+
## Callback في callback
117116

118-
The natural solution would be to put the second `loadScript` call inside the callback, like this:
117+
كيف يمكننا تحميل نصين على التوالي: الأول والثاني بعده؟
118+
119+
الحل الطبيعي أن نضع أستدعاء ال `loadScript` الثاني داخل دالة الcallback, مثل هذا:
119120

120121
```js
121122
loadScript('/my/script.js', function(script) {
@@ -131,9 +132,9 @@ loadScript('/my/script.js', function(script) {
131132
});
132133
```
133134

134-
After the outer `loadScript` is complete, the callback initiates the inner one.
135+
بعد اكتمال "loadScript" الخارجي ، يبدأ الاستدعاء الداخلي.
135136

136-
What if we want one more script...?
137+
ماذا لو أردنا اكثر من برنامج نصي آخر ...؟
137138

138139
```js
139140
loadScript('/my/script.js', function(script) {
@@ -142,7 +143,7 @@ loadScript('/my/script.js', function(script) {
142143

143144
*!*
144145
loadScript('/my/script3.js', function(script) {
145-
// ...continue after all scripts are loaded
146+
// ...استمر بعد تحميل جميع البرامج النصية
146147
});
147148
*/!*
148149

@@ -151,13 +152,13 @@ loadScript('/my/script.js', function(script) {
151152
});
152153
```
153154

154-
So, every new action is inside a callback. That's fine for few actions, but not good for many, so we'll see other variants soon.
155+
لذا ، فإن كل عمل جديد يكون داخل دالة ال callback. هذا جيد لبعض الإجراءات ، ولكن ليس جيدًا للعديد ، لذلك سنرى متغيرات أخرى قريبًا.
155156

156-
## Handling errors
157+
## معالجة الأخطاء
157158

158-
In the above examples we didn't consider errors. What if the script loading fails? Our callback should be able to react on that.
159+
في الأمثلة المذكورة أعلاه لم نعتبر الأخطاء. ماذا لو فشل تحميل البرنامج النصي؟ يجب أن يكون دالة callback الخاص بنا قادرًا على الرد على ذلك.
159160

160-
Here's an improved version of `loadScript` that tracks loading errors:
161+
فيما يلي نسخة محسنة من `loadScript` الذي يتتبع أخطاء التحميل:
161162

162163
```js
163164
function loadScript(src, callback) {
@@ -173,32 +174,32 @@ function loadScript(src, callback) {
173174
}
174175
```
175176

176-
It calls `callback(null, script)` for successful load and `callback(error)` otherwise.
177+
أنها تستدعي `callback(null, script)` للتحميل الناجح وتستدعي `callback(error)` لغير ذلك.
177178

178-
The usage:
179+
الاستخدام:
179180
```js
180181
loadScript('/my/script.js', function(error, script) {
181182
if (error) {
182-
// handle error
183+
// معالجة الخطأ هنا
183184
} else {
184-
// script loaded successfully
185+
// البرنامج النصي تم تحميله بنجاح
185186
}
186187
});
187188
```
188189

189-
Once again, the recipe that we used for `loadScript` is actually quite common. It's called the "error-first callback" style.
190+
مره أخري, الوصفة التي أستخدامناها لل `loadScript` هي في الواقع شائعة جداً. تُسمي النمط "error-first callback".
190191

191-
The convention is:
192-
1. The first argument of the `callback` is reserved for an error if it occurs. Then `callback(err)` is called.
193-
2. The second argument (and the next ones if needed) are for the successful result. Then `callback(null, result1, result2…)` is called.
192+
الاتفاقية هي:
193+
1. الوسيطة الأولى لـ `callback` محجوزة لخطأ إذا حدث. ثم يتم أستدعاء ال `callback(err)`.
194+
2. الوسيطة الثانية (وواحدة اخري أذا احتاجنا) تكون للنتيجة الناجحة. ثم يتم أستدعاء ال `callback(null, result1, result2…)`.
194195

195-
So the single `callback` function is used both for reporting errors and passing back results.
196+
لذلك يتم استخدام وظيفة `callback` الفردية للإبلاغ عن الأخطاء وإرجاع النتائج.
196197

197-
## Pyramid of Doom
198+
## هرم الموت
198199

199-
From the first look, it's a viable way of asynchronous coding. And indeed it is. For one or maybe two nested calls it looks fine.
200+
من النظرة الأولى ، إنها طريقة قابلة للتطبيق للتشفير غير المتزامن. وهو كذلك بالفعل. بالنسبة لأستدعاء واحد أو ربما أستدعائين متداخليين ، تبدو جيدة.
200201

201-
But for multiple asynchronous actions that follow one after another we'll have code like this:
202+
ولكن بالنسبة إلى العديد من الإجراءات غير المتزامنة التي تتبع واحدًا تلو الآخر ، سيكون لدينا كود مثل هذا:
202203

203204
```js
204205
loadScript('1.js', function(error, script) {
@@ -228,14 +229,14 @@ loadScript('1.js', function(error, script) {
228229
});
229230
```
230231

231-
In the code above:
232-
1. We load `1.js`, then if there's no error.
233-
2. We load `2.js`, then if there's no error.
234-
3. We load `3.js`, then if there's no error -- do something else `(*)`.
232+
في الكود الذي بالأعلي:
233+
1. نحن نحمل ال `1.js`, أذا لم يكن هناك خطأ.
234+
2. نحن نحمل ال `2.js`, أذا لم يكن هناك خطأ.
235+
3. نحن نحمل ال `3.js`, أذا لم يكن هناك خطأ -- أفعل بعض الشئ غيره `(*)`.
235236

236-
As calls become more nested, the code becomes deeper and increasingly more difficult to manage, especially if we have real code instead of `...` that may include more loops, conditional statements and so on.
237+
عندما تصبح الأستدعاءات أكثر تداخلًا ، تصبح الشفرة أعمق وتزداد صعوبة إدارتها ، خاصة إذا كان لدينا رمز حقيقي بدلاً من `...` قد يتضمن المزيد من الحلقات ، والعبارات الشرطية وما إلى ذلك.
237238

238-
That's sometimes called "callback hell" or "pyramid of doom."
239+
وهذا ما يُطلق عليه أحيانًا "أسترجاع الجحيم" أو "هرم الموت".
239240

240241
<!--
241242
loadScript('1.js', function(error, script) {
@@ -263,11 +264,11 @@ loadScript('1.js', function(error, script) {
263264

264265
![](callback-hell.svg)
265266

266-
The "pyramid" of nested calls grows to the right with every asynchronous action. Soon it spirals out of control.
267+
ينمو "هرم" الأستدعاءات المتداخلة إلى اليمين مع كل إجراء غير متزامن. سرعان ما يخرج عن السيطرة.
267268

268-
So this way of coding isn't very good.
269+
لذا فإن طريقة كتابة الكود هذه ليست جيدة جدًا.
269270

270-
We can try to alleviate the problem by making every action a standalone function, like this:
271+
يمكننا محاولة التخفيف من المشكلة عن طريق جعل كل عمل وظيفة قائمة بذاتها ، مثل هذا:
271272

272273
```js
273274
loadScript('1.js', step1);
@@ -294,17 +295,17 @@ function step3(error, script) {
294295
if (error) {
295296
handleError(error);
296297
} else {
297-
// ...continue after all scripts are loaded (*)
298+
// ...يتم تنفيذ الاكواد هنا بعد تحميل كل الملفات (*)
298299
}
299300
};
300301
```
301302

302-
See? It does the same, and there's no deep nesting now because we made every action a separate top-level function.
303+
نرى؟ إنه يفعل نفس الشيء ، ولا يوجد تداخل عميق الآن لأننا جعلنا كل إجراء وظيفة منفصلة من المستوى الأعلى.
303304

304-
It works, but the code looks like a torn apart spreadsheet. It's difficult to read, and you probably noticed that one needs to eye-jump between pieces while reading it. That's inconvenient, especially if the reader is not familiar with the code and doesn't know where to eye-jump.
305+
إنه يعمل ، لكن الرمز يبدو وكأنه جدول بيانات ممزق. من الصعب قراءتها ، وربما لاحظت أن المرء يحتاج إلى القفز بين القطع أثناء قراءتها. هذا غير مريح ، خاصة إذا لم يكن القارئ على دراية بالكود ولا يعرف أين يقفز.
305306

306-
Also, the functions named `step*` are all of single use, they are created only to avoid the "pyramid of doom." No one is going to reuse them outside of the action chain. So there's a bit of namespace cluttering here.
307+
أيضاً, الدوال التي تم تسميتها `step*` كلها تستخدم علي حدي, يتم إنشاؤها فقط لتجنب "هرم الموت". لا أحد سيعيد استخدامها خارج سلسلة العمل. لذلك هناك القليل من فوضى مساحة الاسم هنا.
307308

308-
We'd like to have something better.
309+
نود الحصول على شيء أفضل.
309310

310-
Luckily, there are other ways to avoid such pyramids. One of the best ways is to use "promises," described in the next chapter.
311+
لحسن الحظ ، هناك طرق أخرى لتجنب مثل هذه الأهرامات. أحد أفضل الطرق هو استخدام "promises" الموضحة في الفصل التالي.

0 commit comments

Comments
 (0)