Menu
CoddyTech

Async وAwait

جزء من قسم أساسيات Node.js في رحلة Node.js على Coddy. الدرس 23 من 33.

تُقرأ سلسلة من استدعاءات .then على نحو مختلف عن الطريقة التي تفكر بها في الخطوات: اقرأ، ثم حلّل، ثم احفظ.

داخل دالة async، يتوقف await مؤقتًا حتى يستقر الوعد، ويعطيك قيمته. إذا أخفق الوعد، فسيُطلق خطأ عندها، لذا يتولى try وcatch التعامل معه. وفي الوحدة، يعمل await أيضًا على المستوى الأعلى.

import { readFile } from 'node:fs/promises';

const loadConfig = async () => {
    try {
        return JSON.parse(await readFile('config.json', 'utf8'));
    } catch {
        return {};
    }
};

const config = await loadConfig();
console.log(config.port ?? 3000);

تعيد دالة async وعدًا دائمًا، لذا ينتظرها المستدعي باستخدام await أيضًا. إذا نسيت await، فستحصل على الوعد نفسه، Promise { <pending> }، بدلًا من قيمته.

challenge icon

التحدي

سهل

تفتح هذه الخطوة مشروع أداة سطر الأوامر للملاحظات المُعدّة في الدورة، وليس ملفات مشروعك من درس Promises (بما فيها count.js). يبقى عملك السابق في درسه الخاص. اقرأ الملفات المرفقة قبل تعديل store.js. تحتوي هذه النسخة على قارئ الملاحظات المعتمد على الوعود ومعالجة الأخطاء الخاصة به.

يستخدم store.js الآن نسختَي الوعود من readFile وwriteFile، وأصبحت طرائقه async. لكن لا شيء ينتظر اكتمال الوعود حتى الآن، لذا تتعطل كل الأوامر. أضف await في كل موضع يجب أن يكتمل فيه وعد قبل الخطوة التالية.

  1. في store.js، داخل load، انتظر اكتمال readFile قبل أن يستخدم JSON.parse النص.
  2. في store.js، الدالة load هي async، لذا فهي تُرجع وعدًا. انتظره في الموضع الذي يعيّن فيه المخزن قيمة notes. يمكن للوحدة استخدام await في المستوى الأعلى، خارج أي دالة.
  3. في store.js، انتظر اكتمال writeFile في save، وانتظر اكتمال this.save() في add وremove.
  4. في notes.js، أصبحت store.add وstore.remove الآن async. انتظرهما في فرعي add وdone، كي يحتوي n وremoved على قيم لا وعود.

وهكذا يصبح لديك سبعة مواضع لاستخدام await إجمالًا. عندئذٍ يعمل كل أمر كما كان من قبل. يعرض list الملاحظات الموجودة في notes.json. مع ملاحظتَي البداية، يطبع add Buy bread العبارة Saved note 3.، ثم يطبع done 1 العبارة Done: Buy milk.

جرّب ذلك: اكتب list في المربع بعد $ node notes.js قبل أن تغيّر أي شيء. سترى notes.json is damaged: ...، لكن الملف سليم: فقد أُعطي JSON.parse وعدًا بدلًا من نص الملف. بعد إجراء تغييراتك، يعرض list الملاحظات مجددًا. ثم اكتب add Buy bread وسترى Saved note 3.. اكتب done 1 وسترى Done: Buy milk.

جرّب بنفسك

import { existsSync } from 'node:fs';
import { readFile, writeFile } from 'node:fs/promises';

const file = 'notes.json';

// تُرجع readFile وwriteFile الآن وعودًا. انتظر كلًّا منهما باستخدام await.
const load = async () => {
    if (!existsSync(file)) {
        return [];
    }
    try {
        return JSON.parse(readFile(file, 'utf8'));
    } catch (err) {
        console.error(`notes.json is damaged: ${err.message}`);
        process.exit(1);
    }
};

const store = {
    notes: load(),
    async save() {
        writeFile(file, JSON.stringify(this.notes, null, 2));
    },
    async add(text) {
        this.notes.push(text);
        this.save();
        return this.notes.length;
    },
    async remove(n) {
        const [text] = this.notes.splice(n - 1, 1);
        this.save();
        return text;
    },
};

export default store;
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس أساسيات Node.js

تدرّب بنفسك: Playground لـ Express