اثر متقابل
اثر متقابل
در مورد فرضیاتی که ممکن است در این شرایط انجام دهید بسیار محتاط باشید. برای مثال، برای یک توسعهدهنده غیرمعمول نیست که ببیند «http://some.url.2» «همیشه» بسیار کندتر از «http://some.url.1» پاسخ میدهد، شاید به خاطر چه وظایفی باشد. آنها این کار را انجام میدهند (به عنوان مثال، یکی یک وظیفه پایگاه داده را انجام میدهد و دیگری فقط یک فایل استاتیک را واکشی میکند)، بنابراین به نظر میرسد ترتیب مشاهده شده همیشه مطابق انتظار است. حتی اگر هر دو درخواست به یک سرور بروند و عمداً به ترتیب خاصی پاسخ دهد، هیچ تضمینی وجود ندارد که پاسخها به چه ترتیبی به مرورگر برمیگردند.
بنابراین، برای رسیدگی به چنین شرایط مسابقه ای، می توانید تعامل سفارش را هماهنگ کنید:
var res = [];
function response(data) {
if (data.url == “http://some.url.1”) {
res[0] = data;
} e
lse if (data.url == “http://some.url.2”) {
res[1] = data;
}
} /
/ ajax(..) is some arbitrary Ajax function given by a library
ajax( “http://some.url.1”, response );
ajax( “http://some.url.2”, response );
صرف نظر از اینکه کدام پاسخ Ajax ابتدا برمی گردد، ما data.url را بررسی می کنیم (البته با فرض اینکه یکی از سرور برگردانده شده است!) تا بفهمیم که داده های پاسخ باید کدام موقعیت را در آرایه res اشغال کنند. res[0] همیشه نتایج “http://some.url.1” و res[1] همیشه نتایج “http://some.url.2” را نگه می دارد. از طریق هماهنگی ساده، ما عدم قطعیت “شرط نژاد” را حذف کردیم.
اگر چندین فراخوانی تابع همزمان از طریق DOM مشترک با یکدیگر تعامل داشته باشند، استدلال مشابهی از این سناریو اعمال خواهد شد، مانند اینکه یکی محتویات <div> را به روز می کند و دیگری سبک یا ویژگی های <div> را به روز می کند (به عنوان مثال، به عنصر DOM را هنگامی که محتوا داشت قابل مشاهده کنید). احتمالاً نمی خواهید عنصر DOM را قبل از اینکه محتوا داشته باشد نشان دهید، بنابراین هماهنگی باید از تعامل صحیح سفارش اطمینان حاصل کند.
برخی از سناریوهای همزمانی همیشه (نه فقط گاهی) بدون تعامل هماهنگ شکسته می شوند.
در نظر بگیرید:
var a, b;
function foo(x) {
a = x * 2;
baz();
} f
unction bar(y) {
b = y * 2;
baz();
} f
unction baz() {
console.log(a + b);
} /
/ ajax(..) is some arbitrary Ajax function given by a library
ajax( “http://some.url.1”, foo );
ajax( “http://some.url.2”, bar );
در این مثال، چه foo() یا bar() ابتدا شلیک شود، همیشه باعث می شود baz() خیلی زود اجرا شود (یا a یا b هنوز تعریف نشده است)، اما فراخوانی دوم baz() کار خواهد کرد، زیرا هر دو a و b در دسترس خواهند بود.
راه های مختلفی برای رسیدگی به چنین شرایطی وجود دارد. در اینجا یک راه ساده وجود دارد:
var a, b;
function foo(x) {
a = x * 2;
if (a && b) {
baz();
}
} f
unction bar(y) {
b = y * 2;
if (a && b) {
baz();
}
}
function baz() {
console.log( a + b );
} /
/ ajax(..) is some arbitrary Ajax function given by a library
ajax( “http://some.url.1”, foo );
ajax( “http://some.url.2”, bar );
شرطی if (a &&b) در اطراف فراخوانی baz() به طور سنتی “gate” نامیده می شود، زیرا ما مطمئن نیستیم که a و b چه دستوری می رسند، اما منتظر می مانیم تا هر دوی آنها به آنجا برسند قبل از اینکه به آن ادامه دهیم. گیت را باز کنید (با() را فراخوانی کنید).
قوانین ارسال دیدگاه در سایت