آشنایی با Actionها در Mutations

Familiarity with Actions in Mutations

Vue.JS 2: آشنایی با action ها در mutations - قسمت 94

ما در جلسه قبل با mutation ها آشنا شدیم که روش استانداردی برای تغییر state محسوب می شوند اما هنوز نکاتی از آن ها باقی مانده است که باید به آن ها توجه کنیم. مسئله اولی که مورد بحث ما است مبحث synchronous بودن بودن mutation ها است. کلمه synchronous در ایران به کلماتی مانند «همگام» یا «متقارن» معنی شده است. از نظر لغوی ترجمه صحیح تر، «همگام» است اما به هر حال اگر این دو کلمه را شنیده اید، باید بدانید که به چه چیزی اشاره می کنند. در حال حاضر mutation های ما همگی synchronous یا همگام هستند و هیچ گاه نباید درون این mutation ها از کدهای نامتقارن استفاده کنید. همگام بودن یک mutation به معنی این است که mutation باید به صورت کامل اجرا شود تا mutation یا عملیات های دیگر انجام شوند و نمی توانیم هر دو عملیات را در کنار هم و در حال اجرا داشته باشیم.

یک نمونه از کدهای ناهمگام استفاده از تابع جاوا اسکریپتی setTimeout است که پس از چند ثانیه کار خاصی را انجام می دهد. مثالی دیگر از عملیات های ناهمگام، ارسال درخواست به سرور و انتظار برای پاسخ سرور است. اگر از چنین کدهایی درون mutation های خودتان استفاده کنید، دچار مشکل می شوید. mutation های شما باید همیشه synchronous (همگام یا متقارن) باشند.

یکی از مهم ترین مزایای mutation ها این است که بتوانیم تشخیص دهیم کدام mutation در چه زمانی باعث تغییر state ما شده است اما اگر بخواهیم عملیات های asynchronous را درون آن انجام بدهیم دیگر مشخص نخواهد شد کدام mutation مسئول تغییر state است. چرا؟ به دلیل اینکه ممکن است mutation اول از نوع async باشد و به دلیل تاخیر در اجرا، پس از mutation دوم اجرا شود. حالا ترتیب mutation ها کاملا بهم ریخته است و کدها طبق انتظارات شما اجرا نخواهند شد. مثلا تصور کنید که کاربر بخواهد کد تخفیفی را برای محصولی استفاده کند. اگر این عملیات به صورت async اجرا شود، ممکن است فاکتور، با قیمت نشان داده شده به کاربر یکی نباشد و باعث گیج شدن کاربر شود.

مسئله اینجاست که نیاز ما به انجام عملیات های ناهمگام (async) غیر قابل انکار است. ما دائما در حال تبادل داده با سرور هستیم و نمی توانیم آن را نادیده بگیریم. بنابراین چطور می توانیم این مشکل را حل کنیم؟ VueX برای حل این مشکل از قابلیتی به نام Action استفاده می کند. Action ها یک واحد میانی بین کامپوننت و mutation هستند که عملیات های async را اجرا کرده و سپس تغییر را commit می کنند. به عبارت دیگر کامپوننت ما به action می گوید که فلان عملیات async را انجام بده. action آنقدر منتظر می ماند که عملیات async تمام شود و پس از آن commit را انجام می دهد. بدین صورت هیچ کدام از مشکلات قبلی پیش نخواهد آمد.

نحوه ی کارکرد action ها در VueX
نحوه کارکرد action ها در VueX

برای اینکه یک عملیات ناهمگام را شبیه سازی کنم تا action ها را در عمل ببینیم، از setTimeout استفاده می کنم تا پس از کلیک روی یکی از دکمه های برنامه، چند ثانیه طول بکشد و سپس counter تغییر کند اما قبل از آن به فایل store.js می رویم تا یک action را تعریف کنیم:

export const store = new Vuex.Store({
    state: {
        counter: 0
    },
    getters: {
        doubleCounter: state => {
            return state.counter * 2;
        },
        stringCounter: state => {
            return state.counter + ' Clicks';
        }
    },
    mutations: {
        increment: state => {
            state.counter++;
        },
        decrement: state => {
            state.counter--;
        }
    },
    actions: {
        increment: context => {
            context.commit('increment');
        }
    }
});

نحوه تعریف action ها به شکل بالا است. یعنی مثل mutations یک آرگومان به صورت خودکار دریافت می کنید که context نام دارد. این آرگومان به ما اجازه می دهد که به بسیاری از خصوصیات و قابلیت های store خودمان (مانند getter ها و commit و غیره) دسترسی داشته باشیم. در واقع context مانند store است با این تفاوت که تمام قابلیت های store را ندارد. کد بالا یک کد ساده است که واقعا عملیات async خاصی را انجام نمی دهد و فقط برای یادگیری Syntax یا نحو آن را آورده ام. در این کد از طریق context متد commit را صدا می زنیم و سپس increment را به آن پاس می دهیم. توجه داشته باشید که نام action ما در اینجا increment است اما مقدار increment پاس داده شده به context.commit به mutation ما با نام increment اشاره دارد. یعنی باید نام mutation خودتان را به context.commit پاس بدهید.

باید نکته جالبی را هم به شما بگویم. اگر فقط بخواهیم commit را صدا بزنیم، می توانیم از قابلیت destructuring در ES6 استفاده کنیم تا فقط و فقط متد commit را از شیء context بگیریم:

actions: {
    increment: ({ commit }) => {
        commit('increment');
    }
}

اگر با object destructuring در ES6 آشنا نیستید، در مورد آن جست و جو کنید.

نکته بعدی و مهمی که باید بدانیم، مسئله اعمال استاندارد mutation ها است. معمولا پیشنهاد می شود برای نظر بیشتر، همیشه از action ها استفاده کنید، حتی اگر کدهایتان async نیستند. این کار باعث می شود همه چیز منظم تر اجرا شود. حتی اگر برنامه ای دارید که فقط یک عملیات async دارد بهتر است برای تمام عملیات ها از action ها استفاده کنید. بنابراین می توان به صورت زیر جمع بندی کرد:

  • حالت اجباری: اگر کدهای شما دارای عملیات async (ناهمگام) باشد، باید برای آن قسمت از کدها از action ها استفاده کنید.
  • حالت اختیاری: اگر کدهای شما دارای عملیات async (ناهمگام) نباشد، نیازی نیست که از action ها استفاده کنید و می توانید mutation ها را مستقیما صدا بزنید.
  • حالت پیشنهادی: بر اساس نظر اکثر برنامه نویسان، بهتر است همیشه و برای تمام درخواست ها (چه async و چه sync) از action ها استفاده کنید. ما در این دوره از این حالت استفاده می کنیم.

من یک action دیگر را برای decrement و چند action دیگر برای حالت Async نیز می نویسم:

actions: {
    increment: ({ commit }) => {
        commit('increment');
    },
    decrement: ({ commit }) => {
        commit('decrement');
    },
    asyncIncrement: ({ commit }) => {
        setTimeout(() => {
            commit('increment');
        }, 1000);
    },
    asyncDecrement: ({ commit }) => {
        setTimeout(() => {
            commit('decrement');
        }, 1000);
    }
}

همانطور که می بینید دو Action اول کاری به جز اضافه کردن و کم کردن counter انجام نمی دهند (mutation های ما را صدا می زنند) اما دو action دوم، یک ثانیه صبر کرده و سپس mutation ها را صدا می زنند. برای استفاده از این action ها می توانیم به فایل AnotherCounter.vue رفته و به جای mapMutations از mapActions استفاده کنیم. این کار را در جلسه بعدی انجام خواهیم داد.

windows 7 enterprise lizenz kaufen

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری آموزش رایگان Vue js از صفر تا صد توصیه می‌کند:
نویسنده شوید
دیدگاه‌های شما (2 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

محمد شجاع
01 بهمن 1400
واقعا دمتون گرم چقدر کامل توضیح دادین و با جزییات مشخصه برای این دوره اموزش رحمت کشیده شده ، یک دنیا تشکر

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

Amir Nouri
29 مهر 1400
ادامه بده استادد اگه رو کد پین یا .. هم بزاری عالی میشه

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.