אינטרנט ישראל
  • ראשי
  • אודות רן בר-זיק ואינטרנט ישראל
  • ערוץ טלגרם
  • מסטודון
  • התחברו אלי בטוויטר
  • התחברו אלי בלינקדאין
  • ספר ג'אווהסקריפט
  • ראשי
  • אודות רן בר-זיק ואינטרנט ישראל
  • ערוץ טלגרם
  • מסטודון
  • התחברו אלי בטוויטר
  • התחברו אלי בלינקדאין
  • ספר ג'אווהסקריפט
ראשי » מדריכים » ES20XX » Promise.any

Promise.any

רן בר-זיק ינואר 24, 2021 7:07 am 2 תגובות

מתודה חדשה ל-Promise מאפשרת ניהול יותר טוב של פרומיסים מרובים.

»ES2021 replaceAll
»ES2021 private methods
כדאי תמיד להשאר מעודכנים! אם יש לכם טלגרם, בדקו את ערוץ הטלגרם של האתר שבו אני מעדכן על פוסטים חדשים 🙂 אם אתם רוצים ללמוד תכנות באופן מקיף ומסודר, הצטרפו לאלפי הלומדים בפרויקט "ללמוד ג'אווהסקריפט בעברית" שמלמד לתכנת בג'אווהסקריפט, ב-Node.js ובריאקט וגם מלמד על תרומה לקוד פתוח. גם ספרים דיגיטליים וגם ספרים מודפסים. בשיתוף הקריה האקדמית אונו ובתמיכת חברות מובילות כגון Wix, Outbrain, Elementor, Iron Source, Chegg, Really Good ועוד.

אחת התוספות הממש חביבות ב-ES2021 הוא ה-any. מתודה שמגיעה עם הפרומיס שבו אנו משתמשים בתכנות אסינכרוני (לא מכירים? זה הזמן! הנה המאמר שלי עליו שכתבתי בתקופה הפרהיסטורית של 2016, אל תשכחו גם את ה-async await!).

אז הנה promise והנה השימוש הבסיסי בו:

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('Promise 1'), Math.floor(Math.random() * 1000));
});
p1.then(res => console.log(res)); // Promise 1

אנו כמובן יכולים להשתמש ב-async await כדי להשתמש בפרומיס:

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('Promise 1'), Math.floor(Math.random() * 1000));
});

async function callPromise() {
  const res = await p1;
  console.log(res);
};
callPromise(); // Promise 1

כיוון ש-async await זו הדרך המודרנית, אני אשתמש בה בהמשך המאמר. אני רק מזכיר שמדובר בפיצ'ר של ES2017 אז אם אתם לא מכירים, זו ההזדמנות להכיר.

טוב, הכל מעולה, אבל מה קורה אם יש לנו כמה פרומיסים? איך אני מנהל אותם? אני יכול לקרוא לאחד אחרי השני.

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('Promise 1'), Math.floor(Math.random() * 1000));
});
const p2 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('Promise 2'), Math.floor(Math.random() * 1000));
});
const p3 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('Promise 3'), Math.floor(Math.random() * 1000));
});

async function callPromise() {
  let res = await p1;
  console.log(res);
  res = await p2;
  console.log(res);
  res = await p3;
  console.log(res);
};
callPromise(); // Promise 1, Promise 2, Promise 3

בעוד שמדובר בדרך לגיטימית, זו דרך מאוד לא יעילה לעבוד בה אם אני רוצה לשגר את כל הפרומיסים ביחד. פה אני קורא ל-p1, מחכה שהוא יסתיים, קורא ל-p2, מחכה שהוא יסתיים, קורא ל-p3 ומחכה שהוא יסתיים וכך הלאה. אם אחת מהן נכשלת, אז השניים האחרות לא יצאו. זה לא ממש מוצלח אם שאר הקריאות לא תלויות זו בזו.

אם אני רוצה שכולן יצאו בבת אחת אני אשתמש ב-all. כך:

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('Promise 1'), Math.floor(Math.random() * 1000));
});
const p2 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('Promise 2'), Math.floor(Math.random() * 1000));
});
const p3 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('Promise 3'), Math.floor(Math.random() * 1000));
});

async function callPromise() {
  let res = await Promise.all([p1,p2,p3]);
  console.log(res);
};
callPromise(); // ["Promise 1", "Promise 2", "Promise 3"]

זה מנוהל יותר טוב, אבל אם פרומיס אחד נכשל? הכל נכשל. לא נקבל תוצאה אחת אפילו אלא error. זה יכול להיות סבבה אם אני רוצה שכולן יצליחו. אבל מה אם אני רוצה שכל הפרומיסים יישלחו ואני לא רוצה שגיאה אם הם ייכשלו? אז יש לי את allSettled שעליו גם כתבתי בעבר – הוא יצא בשנה הקודמת:

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('Promise 1'), Math.floor(Math.random() * 1000));
});
const p2 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('Promise 2'), Math.floor(Math.random() * 1000));
});
const p3 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('Promise 3'), Math.floor(Math.random() * 1000));
});

async function callPromise() {
  let res = await Promise.allSettled([p1,p2,p3]);
  console.log(res);
};
callPromise(); 
/*
[{status: "fulfilled", value: "Promise 1"},
{status: "fulfilled", value: "Promise 2"},
{status: "fulfilled", value: "Promise 3"},
*/

יש לנו גם את race. שהוא מחזיר את הפרומיס שחזרה הכי מהר בלי קשר להצלחה או לכשלון – מה זאת אומרת? זה אומרת שאם פרומיס אחד עושה reject, אנו מקבלים error.

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('Promise 1'), Math.floor(Math.random() * 1000));
});
const p2 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('Promise 2'), Math.floor(Math.random() * 1000));
});
const p3 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('Promise 3'), Math.floor(Math.random() * 1000));
});

async function callPromise() {
  let res = await Promise.race([p1,p2,p3]);
  console.log(res);
};
callPromise(); // Maybe 1, 2 or 3

וזה? זה יכול לבאס מאוד. כי אם אני רוצה את הפרומיס הראשון שמצליח – לא זה שמחזיר לי תשובה, זה עלול להיות סופר בעייתי. בדיוק בשביל זה יש לי את any. הוא עובד בול כמו race, אבל רק על פרומיסים שמצליחים!

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('Promise 1'), Math.floor(Math.random() * 1000));
});
const p2 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('Promise 2'), Math.floor(Math.random() * 1000));
});
const p3 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('Promise 3'), Math.floor(Math.random() * 1000));
});

async function callPromise() {
  let res = await Promise.any([p1,p2,p3]);
  console.log(res);
};
callPromise(); // Maybe 1, 2 or 3

אם יש אחד שייכשל? ה-any לא יזרוק שגיאה, הוא פשוט יתעלם ויחכה לפרומיס הבא שיצליח.

const p1 = new Promise((resolve, reject) => reject('Promise 1 fail'));
const p2 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('Promise 2'), Math.floor(Math.random() * 1000));
});
const p3 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('Promise 3'), Math.floor(Math.random() * 1000));
});

async function callPromise() {
  let res = await Promise.any([p1,p2,p3]);
  console.log(res);
};
callPromise(); // Maybe 2 or 3, never 1!

ומה קורה עם כולם נכשלים? אז פה יש לנו שגיאה.

const p1 = new Promise((resolve, reject) => reject('Promise 1 fail'));
const p2 = new Promise((resolve, reject) => reject('Promise 2 fail'));
const p3 = new Promise((resolve, reject) => reject('Promise 3 fail'));

async function callPromise() {
  try {
    let res = await Promise.any([p1,p2,p3]);
    console.log(res);
  } catch(e) {
    console.log(e); 
  }
};

callPromise(); // AggregateError: All promises were rejected

מדובר בעוד כלי בארסנל של הפרומיסים שמאפשר לנהל פרומיסים מרובים בהתאם לצורך ומאפשר גמישות גדולה עם קוד אלגנטי. יופי של תוספת ל-2021.

כדאי תמיד להשאר מעודכנים! אם יש לכם טלגרם, בדקו את ערוץ הטלגרם של האתר שבו אני מעדכן על פוסטים חדשים 🙂 אם אתם רוצים ללמוד תכנות באופן מקיף ומסודר, הצטרפו לאלפי הלומדים בפרויקט "ללמוד ג'אווהסקריפט בעברית" שמלמד לתכנת בג'אווהסקריפט, ב-Node.js ובריאקט וגם מלמד על תרומה לקוד פתוח. גם ספרים דיגיטליים וגם ספרים מודפסים. בשיתוף הקריה האקדמית אונו ובתמיכת חברות מובילות כגון Wix, Outbrain, Elementor, Iron Source, Chegg, Really Good ועוד.
es2021

2 תגובות

  1. שי הגב ינואר 24, 2021 בשעה 8:29 pm

    יש לך רעיון ל use case ?

    • Tapeta הגב מרץ 4, 2021 בשעה 10:09 pm

      למשל אם יש עניין של performance על המילישניות (דוגמא טובה serverless).
      ובמקרה אתה משתמש ב-CDNs, אז כמובן אפשר לבדוק באיזה region נמצא ה-user וככה להחזיק dict של CDNs ע"פ region, ובנוסף אפשר להשתמש גם ב-Promise.Any בשביל לפנות לכל אלו שנמצאים ב-region הנוכחי ולקבל את הראשון שחוזר.

      וכן הלאה דוגמאות שונות של performance, אולי lambda vs google function כשאתה מחזיק את שניהם רק בשביל ה-perf ולא אכפת לך אפילו מ-cost, אלא רק שיהיה מהיר.

      ובטח שיש דוגמאות הרבה יותר טובות מאלו.

השארת תגובה

ביטול

ללמוד ג'אווהסקריפט בעברית

ללמוד לתכנת ג'אווהסקריפט בעברית שגייס יותר משלוש מאות אלף שקל ולמעלה מ-2000 תומכים - בואו ללמוד עכשיו איך לתכנת.

רשימת הנושאים
  • מדריכים
    • ריאקט
    • טייפסקריפט
    • ECMAScript 6
    • ES20XX
    • Node.js
    • Express
    • רספברי פיי
    • Babel
    • docker
    • MongoDB
    • Git
    • לימוד MySQL
    • SASS
    • jQuery
    • CSS3
    • HTML 5
    • SVN
    • LESS
  • פיתוח אינטרנט
    • פתרונות ומאמרים על פיתוח אינטרנט
    • jQuery Scripts
    • jQuery למתקדמים
    • יסודות בתכנות
    • נגישות אינטרנט
  • חדשות אינטרנט
  • מידע כללי על אינטרנט
    • רשת האינטרנט
    • בניית אתרי אינטרנט
  • rss logo

    לכל המאמרים

    לכל המאמרים שפורסמו באינטרנט ישראל משנת 2008 ועד עכשיו.
  • rss logo

    RSS Feed

    משתמשים בקורא RSS? אם כן, עקבו אחרי אינטרנט ישראל באמצעות פיד ה-RSS!
    מה זה RSS?
  • Twitter logo

    עקבו אחרי בטוויטר

    בחשבון הטוויטר שלי אני מפרסם עדכונים מהירים על חדשות בתחום התכנות והיזמות, התרעות על מצבי חירום ורכילות בוערת על תחום הווב.
    מה זה טוויטר?
  • facebook like image

    ערוץ הטלגרם של אינטרנט ישראל

    בערוץ הטלגרם של אינטרנט ישראל אני מפרסם את הפוסטים של באתר וכן עדכונים טכנולוגיים נוספים.
    מה זה טלגרם?
  • github logo

    הפרויקטים שלי בגיטהאב

    הפרויקטים שאני כותב ושוחררו לציבור ברישיון קוד פתוח נמצאים ברובם בגיטהאב.
חיפוש

כל הזכויות שמורות לרן בר-זיק ולאינטרנט ישראל | מדיניות הפרטיות של אתר אינטרנט ישראל | אתר אינטרנט ישראל נגיש לפי תקן WCAG 2.0 AA | הצהרת הנגישות של האתר | אבטחת מידע ודיווח על בעיית אבטחת מידע

גלילה לראש העמוד