اذهب إلى المحتوى

السؤال

Recommended Posts

  • 1
نشر

تُستخدم الfor await من أجل إتاحة صيغة الfor each ولكن للمُكررات(iterators) التي تقوم بإرجاع promise 

فمثلاً في الطبيعي إن كان لدينا مُكرر كما بالشكل التالي

function* colorIterator() {
    yield "blue";
    yield "red";
}

يمكننا بكل سهولة أن نقوم بالمرور عبره بإستخدام forEach بالشكل التالي

const iterat = colorIterator();

for (const color of iterat) {
    console.log(color);
}

ولكن ماذا إن كان لدينا مُكرر يحتوي على promises ? في تلك الحالة لن تفيدنا كثيراً صيغة الfor each حيث أنها ستقوم بإرجاع promise وليس قيمة , أي أنها ستقوم بإرجاع كائن كما هو بهذا الشكل
 

Promise {<pending>}
[[Prototype]]: Promise
[[PromiseState]]: "pending"
[[PromiseResult]]: undefined

وﻻ نستطيع إستخراج بيانات مفيدة من كائن بهذا الشكل, في الطبيعي كنا نقوم بإستخدام صيغة .then للتعامل مع الpromises كما بهذه الشفرة

my_promise.then(response=>///code)

ولكن ﻻ يمكننا تنفيذ صيغة كتلك في الforeach , الحل أن نقوم إذا بإستخدام صيغة الfor await , فإن كان لدينا مُكرر كالتالي

const asyncIterable = {
  [Symbol.asyncIterator]() {
    return {
      i: 0,
      next() {
        if (this.i < 3) {
          return Promise.resolve({ value: this.i++, done: false });
        }

        return Promise.resolve({ done: true });
      }
    };
  }

والذي ببساطة يحتوي على مجموعة من الpromises تقوم بإرجاع 1, 2, 3

فﻻ نستطيع إستخدام الfor each التقليدية لأننا لن نحصل إلى على promises لم تُعالج بعد, ففي تلك النقطة يجب إستخدام الfor await of كما في الشفرة البرمجية التالية


(async function() {
  for await (let num of asyncGenerator()) {
    console.log(num);
  }

وكما تﻻحظ عزيزي فإن الدالة التي تحتوي على الfor await هي من النوع async حيث ﻻ يمكننا إستخدام تلك الصيغة إلا على الدوال من النوع async 

  • 1
نشر (معدل)

تستخدم for await  مع التكرار غير المتزامنة (asynchronous) و ليس مع المصفوفات (arrays)

Syntax 

for await (variable of iterable) {
  statement
}
  • variable : في كل تكرار ، يتم تعين قيمة خاصية مختلفة إلى متغير مثل const, let, var.
  • iterable : كائن يجب تكرار خصائصه .

 في هذا المثال يقدم fetchCommits طلباً غير متزامن (asynchronous) لجلب commits من GitHub ، سوف يرسل البيانات بـ استخدام JSON مع توفير رابط الصفحة ، لذلك لا يمكن بدأ التكرار إلا بالحصول على الرابط الطلب. 

async function* fetchCommits(repo) {
  let url = `https://api.github.com/repos/${repo}/commits`;

  while (url) {
    const response = await fetch(url, { 
      headers: {'User-Agent': 'Our script'}, 
    });

    const body = await response.json(); // (array of commits

    let nextPage = response.headers.get('Link').match(/<(.*?)>; rel="next"/);
    nextPage = nextPage?.[1];

    url = nextPage;

    for(let commit of body) { 
      yield commit;
    }
  }
}

يمكنك الاطلاع على هذه المقالة لإضافة المزيد من الفائدة 

 

تم التعديل في بواسطة أسامة زيادة

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...