promise all و settled در جاوا اسکریپت
گاها پیش میاد که میخوام چنتا درخواست async رو همزمان اجرا کنیم و جواب همه رو هم یکجا دریافت کنیم. برای اینکار میتونیم از Promise.all استفاده کنیم:
function func() { let a = 'vue'; if (true) { let a = 'vuefarsi'; // اینجا یک مقدار جدید تعریف شده console.log(a); } console.log(a); }func();
توی این کد ما داخل فانکشن اول یک متغیر a تعریف کردیم و مقدار vue رو بهش دادیم. بعد توی if دوباره یک متغیر با همون اسم قبلی یعنی a تعریف کردیم ولی اینبار مقدار vuefarsi رو بهش دادیم. همونطور که می بینید خروجی console.log در if مقدار vuefarsi هست و لاگی که خارج از این بلاک انجام دادیم مقدار vue رو چاپ میکنه. به این میگن variable shadowing. اینجا ما داخل فانکشن یک block scope داریم و داخل if هم یک block scope دیگه داریم. داخل هر scope وقتی متغیری رو تعریف میکنیم (البته اگه از var استفاده نکنیم) فقط داخل همون scope بهش دسترسی داریم. حالا اگه متغیری که داخل if تعریف کردیم رو حذف کنیم console log میره از scope خارجی یعنی a = vue استفاده میکنه. حالا اگه مثلا داخل if بیایم از var استفاده خطای variable already defined رو میگیریم:
const p1 = Promise.resolve(1);const p2 = Promise.resolve(2);const p3 = Promise.reject(3);Promise.all([p1,p2]).then(res => console.log(res)); // [1, 2]Promise.all([p1,p2,p3]).then(res => console.log(res)) // Nothing ReturnsPromise.all([p1,p2,p3]).catch(e => console.log(e)); // 3
توی این متد اگر هر کدوم از این درخواست ها reject بشن در واقع بقیه هم reject میشن و توی then دیگه ما result ای نداریم. در واقع اولین درخواستی که ریجکت بشه بقیه هم ریجکت میشن. حالا شاید نخوایم که این اتفاق بیافته، یعنی میخوایم اونایی که reject میشن رو داشته باشیم، اونایی که resolve میشن رو هم داشته باشیم، اینجاست که متد allSettled به کمک مون میاد:
Promise.allSettled([p1,p2,p3]).then(res => console.log(res));// {status: "fulfilled", value: 1}// {status: "fulfilled", value: 2}// {status: "rejected", reason: 3}