React: рдкрджрд╛рд╡рдирдд `isMounted`

рдХреЛ рдирд┐рд░реНрдорд┐рдд 14 рдирд╡ре░ 2015  ┬╖  48рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: facebook/react

isMounted ES6 рдХрдХреНрд╖рд╛рдУрдВ рдкрд░ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЕрдиреБрдкрд▓рдмреНрдз рд╣реИ, рдФрд░ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рдЪреЗрддрд╛рд╡рдиреА рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдХрд╣рд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рд╣рдо рдЙрдиреНрд╣реЗрдВ "рд╣реЛ рд╕рдХрддрд╛ рд╣реИ" рд╣рдЯрд╛ рджреЗрдВ, рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЙрдиреНрд╣реЗрдВ рдкрджрд╛рд╡рдирдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ github рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИред рдЖрдЬ рдХреА рд╣рдорд╛рд░реА рдЪрд░реНрдЪрд╛ рдХреЗ рдЕрдиреБрд╕рд╛рд░, рд╣рдо рдореВрд▓ рд░реВрдк рд╕реЗ рд╕рд╣рдордд рд╣реИрдВ рдХрд┐ рд╣рдо isMounted рд╕реЗ рджреВрд░ рдЬрд╛рдирд╛ рд╢реБрд░реВ рдХрд░ рджреЗрдВрдЧреЗ рдФрд░ рдЗрд╕реЗ рд╣рдЯрд╛ рджреЗрдВрдЧреЗред рд╣рдореЗрдВ рдЕрднреА рднреА рд╡рд╛рджреЛрдВ (рдФрд░ рд╕рдВрдмрдВрдзрд┐рдд рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЛрдВ) рдХреЗ рдЖрд╕рдкрд╛рд╕ рдХреБрдЫ рдЕрдЪреНрдЫреА рдХрд╣рд╛рдирд┐рдпреЛрдВ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИред

рдпрд╣ рдореБрджреНрджрд╛ рдЙрд╕ рд▓рдХреНрд╖реНрдп рдХреА рдУрд░ рдкреНрд░рдЧрддрд┐ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИред

рдкреГрд╖реНрдарднреВрдорд┐ рдХреЗ рд▓рд┐рдП, рдХреГрдкрдпрд╛ рдкрдврд╝реЗрдВ:

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдХрд┐рд╕реА рднреА рд╡рд╛рджреЗ рдХреЛ рд░рджреНрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рд╕рд░рд▓ рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ

const makeCancelable = (promise) => {
  let hasCanceled_ = false;

  const wrappedPromise = new Promise((resolve, reject) => {
    promise.then((val) =>
      hasCanceled_ ? reject({isCanceled: true}) : resolve(val)
    );
    promise.catch((error) =>
      hasCanceled_ ? reject({isCanceled: true}) : reject(error)
    );
  });

  return {
    promise: wrappedPromise,
    cancel() {
      hasCanceled_ = true;
    },
  };
};

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рд╢реБрджреНрдзрддрд╛/рдкреВрд░реНрдгрддрд╛ рдХреЗ рд▓рд┐рдП рдЕрджреНрдпрддрди рдХрд┐рдпрд╛ рдЧрдпрд╛ред

рдХреИрд╕реЗ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд░реЗ

const somePromise = new Promise(r => setTimeout(r, 1000));

const cancelable = makeCancelable(somePromise);

cancelable
  .promise
  .then(() => console.log('resolved'))
  .catch(({isCanceled, ...error}) => console.log('isCanceled', isCanceled));

// Cancel promise
cancelable.cancel();

рд╕рднреА 48 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рдореИрдВ рдЗрд╕рд╕реЗ рд╕рд╣рдордд рдирд╣реАрдВ рд╣реВрдВред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ ES6 рд╡рд╛рджреЛрдВ рдХреЛ componentWillUnmount рдкрд░ рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рд░реВрдк рд╕реЗ рд░рджреНрдж рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдЬрд╛рдВрдЪрдиреЗ рдХрд╛ рдПрдХрдорд╛рддреНрд░ рддрд░реАрдХрд╛ рд╣реИ рдХрд┐ рдШрдЯрдХ рд╕реЗрдЯрд╕реНрдЯреЗрдЯ рд╕реЗ рдкрд╣рд▓реЗ рдЖрд░реЛрд╣рд┐рдд рд╣реИ рдпрд╛ рдХреЛрдИ рдЕрдиреНрдп рдХреНрд░рд┐рдпрд╛ рдПрд╕рд┐рдВрдХ рдмрдЧ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдХрдард┐рди рд░рд╛рд╕реНрддрд╛ рдЦреЛрд▓ рд░рд╣реА рд╣реИред

@yaycmyk рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд░реЗрдЦрд╛:

рд╣рдореЗрдВ рдЕрднреА рднреА рд╡рд╛рджреЛрдВ (рдФрд░ рд╕рдВрдмрдВрдзрд┐рдд рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЛрдВ) рдХреЗ рдЖрд╕рдкрд╛рд╕ рдХреБрдЫ рдЕрдЪреНрдЫреА рдХрд╣рд╛рдирд┐рдпреЛрдВ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИред

рдХреГрдкрдпрд╛ рдореЗрд░реЗ рджреНрд╡рд╛рд░рд╛ рд╕реВрдЪреАрдмрджреНрдз рдкреГрд╖реНрдарднреВрдорд┐ рдХреЗ рдореБрджреНрджреЛрдВ рдХреЛ рдкрдврд╝реЗрдВ, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ: https://github.com/facebook/react/issues/2787#issuecomment -68738793

рдореИрдВрдиреЗ рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ рдкрдврд╝реАрдВред рдореБрдЭреЗ рдмрд╕ рдореБрджреНрджреЗ рдЕрдЯрдкрдЯреЗ рд▓рдЧрддреЗ рд╣реИрдВред

рд╡рд╛рджреЛрдВ рдХреЛ рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рд░реВрдк рд╕реЗ рд░рджреНрдж рдХреНрдпреЛрдВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛? рдХреЛрдИ рд╕реНрд░реЛрдд/рд╕рдмреВрдд/рдЙрджрд╛рд╣рд░рдг?

рд╕реЛрдорд╡рд╛рд░, 16 рдирд╡рдВрдмрд░, 2015 рдХреЛ, рдЗрд╡рд╛рди рдЬреИрдХрдмреНрд╕ рдиреЛрдЯрд┐рдлрд┐рдХреЗрд╢рди @github.com рдиреЗ рд▓рд┐рдЦрд╛:

рдореИрдВ рдЗрд╕рд╕реЗ рд╕рд╣рдордд рдирд╣реАрдВ рд╣реВрдВред ES6 рд╡рд╛рджреЗ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ
рдХрдВрдкреЛрдиреЗрдВрдЯрд╡рд┐рд▓рдЕрдирдорд╛рдЙрдВрдЯ рдкрд░ рд░рджреНрдж рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдЬрд╛рдВрдЪрдиреЗ рдХрд╛ рдПрдХрдорд╛рддреНрд░ рддрд░реАрдХрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛
рдШрдЯрдХ рд╕реЗрдЯрд╕реНрдЯреЗрдЯ рд╕реЗ рдкрд╣рд▓реЗ рдЖрд░реЛрд╣рд┐рдд рд╣реИ рдпрд╛ рдХреЛрдИ рдЕрдиреНрдп рдХреНрд░рд┐рдпрд╛ рдЦреЛрд▓ рд░рд╣реА рд╣реИ
async рдмрдЧреНрд╕ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдореЗрд╣рдирдд рдХрд░рдиреЗ рдХрд╛ рддрд░реАрдХрд╛ред

@nvartolomei ES6 рд╡рд╛рджрд╛ рдпреБрдХреНрддрд┐ рдХреЛ рджреЗрдЦреЗрдВред

рдпрд╣ рдПрдХ рджреАрд░реНрдШрдХрд╛рд▓рд┐рдХ рд▓рдХреНрд╖реНрдп рд╣реИ, рди рдХрд┐ рдРрд╕рд╛ рдХреБрдЫ рдЬреЛ рддреБрд░рдВрдд рд╣реЛ рд░рд╣рд╛ рд╣реИред рд▓реЗрдХрд┐рди рд╣рдо рдпреЛрдЬрдирд╛ рдФрд░ рдЪрд░реНрдЪрд╛рдУрдВ рдХреЛ рдПрдХ рд╣реА рд╕реНрдерд╛рди рдкрд░ рдЯреНрд░реИрдХ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рди рдХрд┐ рд╣рд░ рдореБрджреНрджреЗ рдкрд░ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рдЬрдм рдпрд╣ рд╕рд╛рдордиреЗ рдЖрддрд╛ рд╣реИред рд╣рдо рд╡рд░реНрддрдорд╛рди рдореЗрдВ рд░рджреНрдж рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╡рд╛рджреЛрдВ рдХреА рд╕рдорд╕реНрдпрд╛ рд╕реЗ рдЕрд╡рдЧрдд рд╣реИрдВ, рдЬреЛ рдПрдХ рдкреНрд░рдореБрдЦ рдХрд╛рд░рдг рд╣реИ рдХрд┐ рд╣рдордиреЗ рдЗрд╕реЗ рдкрд╣рд▓реЗ рд╣реА рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИред

@yaycmyk рдПрдХ рдмрд╣реБрдд рд╣реА рдЬрдЯрд┐рд▓ рдореБрджреНрджреЗ рдХреЛ рдЕрддрд┐-рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП... рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ рдХрд╣ рд░рд╣реА рд╣реИрдВ... рдЕрдирдорд╛рдЙрдВрдЯ рдШрдЯрдХреЛрдВ рдХреЗ рд▓рд┐рдП setState рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП isMounted рдХрд░рдиреЗ рд╕реЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рдорд╛рдзрд╛рди рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ рдХрд┐ setState рдЪреЗрддрд╛рд╡рдиреА рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд░рд╣реА рдереА - рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣ рдХреЗрд╡рд▓ рд╕рдорд╕реНрдпрд╛ рдХреЛ рдЫреБрдкрд╛рддреА рд╣реИред рд╕рд╛рде рд╣реА, рдХрд┐рд╕реА рд╡рд╛рджреЗ рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк setState рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рд╡реИрд╕реЗ рднреА рдПрдХ рд╡рд┐рд░реЛрдзреА рдкреИрдЯрд░реНрди рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рджреМрдбрд╝ рдХреА рд╕реНрдерд┐рддрд┐ рдкреИрджрд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдЬрд░реВрд░реА рдирд╣реАрдВ рдХрд┐ рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗред рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣рдо рдЗрд╕рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдФрд░ рд░рд┐рдПрдХреНрдЯ рдХреЗ рд╕рд╛рде рд╡рд╛рджреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП "рд╕рд░реНрд╡реЛрддреНрддрдо рдЕрднреНрдпрд╛рд╕" рдЕрдиреБрд╢рдВрд╕рд╛ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред

рдореИрдВ рдорд╛рдирддрд╛ рд╣реВрдВ рдХрд┐ рдореБрджреНрджреЗ рдереЛрдбрд╝реЗ рдЙрд▓рдЭреЗ рд╣реБрдП рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдХрд╛рдлреА рд╣рдж рддрдХ рдЗрд╕рд▓рд┐рдП рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдПрдХ рдЬрдЯрд┐рд▓ рдореБрджреНрджрд╛ рд╣реИ рдЬрд┐рд╕реЗ рд╣рдо рдЕрднреА рднреА рд╕рдордЭ рд░рд╣реЗ рд╣реИрдВ рдФрд░ рдЕрднреА рддрдХ рдЗрд╕рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдирд╣реАрдВ рд╣реИред

рдПрдХ рд╡рд╛рджреЗ рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреЗ рд░реВрдк рдореЗрдВ рд╕реЗрдЯрд╕реНрдЯреЗрдЯ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рд╡реИрд╕реЗ рднреА рдПрдХ рд╡рд┐рд░реЛрдзреА рдкреИрдЯрд░реНрди рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рджреМрдбрд╝ рдХреА рд╕реНрдерд┐рддрд┐ рдкреИрджрд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдЬрд░реВрд░реА рдирд╣реАрдВ рдХрд┐ рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗ

рд╣рдо рдЙрд╕ рдкрд░ рдЕрд╕рд╣рдордд рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╣рдордд рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рдРрд╕реЗ рд╕рдордп рд╣реЛрддреЗ рд╣реИрдВ рдЬрдм рд╕рд╛рдордЧреНрд░реА рдХреЛ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд░реВрдк рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ рдФрд░ рдЖрдк рдЙрд╕ рд╕рд╛рдордЧреНрд░реА рдХреЛ рдПрдХ рдмрд╛рд░ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рдкреЙрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреВрд░реНрдг рдкреИрдорд╛рдиреЗ рдкрд░ рдкреБрди: рдкреНрд░рд╕реНрддреБрдд рдХрд░рдирд╛ рдирд╣реАрдВ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдореИрдВ рдЗрд╕реЗ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдПрдХ рдЕрдирдВрдд рддрд╛рд▓рд┐рдХрд╛ рджреГрд╢реНрдп рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ рдЬрд╣рд╛рдВ рдПрдХ рдкреВрд░реНрдг рд╡рд░реНрдЪреБрдЕрд▓ рд░реАрд░реЗрдВрдбрд░ рдЕрдирд╛рд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛ред

рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдХрд┐рд╕реА рд╡рд╛рджреЗ рдХреЛ рд░рджреНрдж рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рди рд╣реЛрдВ, рд▓реЗрдХрд┐рди рдЖрдк рдЗрд╕реЗ рдЕрдирдорд╛рдЙрдВрдЯ рдкрд░ рдШрдЯрдХ рдХреЛ рдЕрд╕рдВрдмрджреНрдз рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреИрд╕реЗ:

const SomeComponent = React.createClass({
    componentDidMount() {
        this.protect = protectFromUnmount();

        ajax(/* */).then(
            this.protect( // <-- barrier between the promise and the component
                response => {this.setState({thing: response.thing});}
            )
        );
    },
    componentWillUnmount() {
        this.protect.unmount();
    },
});

рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЕрдВрддрд░ рдпрд╣ рд╣реИ рдХрд┐ рдЬрдм this.protect.unmount() рдХреЛ componentWillUnmount рдореЗрдВ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╕рднреА рдХреЙрд▓рдмреИрдХ рдбреАрд░реЗрдлрд░реЗрдВрд╕ рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдХрдВрдкреЛрдиреЗрдВрдЯ рдбреАрд░реЗрдлрд░реЗрдВрд╕ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдЬрдм рд╡рд╛рджрд╛ рдкреВрд░рд╛ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рд╕рд┐рд░реНрдл рдиреЛ-рдСрдк рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдЕрдирдорд╛рдЙрдВрдЯ рдХрд┐рдП рдЧрдП рдШрдЯрдХреЛрдВ рдХреЗ рд╡рд╛рджреЛрдВ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдХрд┐рд╕реА рднреА рдореЗрдореЛрд░реА рд▓реАрдХ рдХреЛ рд░реЛрдХрдирд╛ рдЪрд╛рд╣рд┐рдПред рд╕реБрд░рдХреНрд╖рд╛ рдХреЗ рд▓рд┐рдП рд╕реНрд░реЛрдд рд╕реЗ рдЕрдирдорд╛рдЙрдВрдЯ

рдХрд┐рд╕реА рднреА рд╡рд╛рджреЗ рдХреЛ рд░рджреНрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рд╕рд░рд▓ рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ

const makeCancelable = (promise) => {
  let hasCanceled_ = false;

  const wrappedPromise = new Promise((resolve, reject) => {
    promise.then((val) =>
      hasCanceled_ ? reject({isCanceled: true}) : resolve(val)
    );
    promise.catch((error) =>
      hasCanceled_ ? reject({isCanceled: true}) : reject(error)
    );
  });

  return {
    promise: wrappedPromise,
    cancel() {
      hasCanceled_ = true;
    },
  };
};

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рд╢реБрджреНрдзрддрд╛/рдкреВрд░реНрдгрддрд╛ рдХреЗ рд▓рд┐рдП рдЕрджреНрдпрддрди рдХрд┐рдпрд╛ рдЧрдпрд╛ред

рдХреИрд╕реЗ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд░реЗ

const somePromise = new Promise(r => setTimeout(r, 1000));

const cancelable = makeCancelable(somePromise);

cancelable
  .promise
  .then(() => console.log('resolved'))
  .catch(({isCanceled, ...error}) => console.log('isCanceled', isCanceled));

// Cancel promise
cancelable.cancel();

ES6 рд╡рд╛рджреЛрдВ рдХреЛ рд░рджреНрдж рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдмрдирд╛рдиреЗ рдХреЗ рддрд░реАрдХреЛрдВ рдХреЛ рд╕реВрдЪреАрдмрджреНрдз рдХрд░рдирд╛ рдмрд┐рдВрджреБ рдХреЗ рдЕрд▓рд╛рд╡рд╛ рд╣реИред рдЗрд░рд╛рджрд╛ рдПрдХ рд╕рдорд╛рдзрд╛рди рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХрд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдЬреЛ рдХрд▓реНрдкрдирд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдмрдЬрд╛рдп рдХрд▓реНрдкрдирд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

рдореИрдВ рд╕рд╣рдордд рд╣реВрдБред рдХреЗрд╡рд▓ рдпрд╣ рдЬрд╛рдВрдЪрдиреЗ рдХреЗ рдмрдЬрд╛рдп рдХрд┐ рдХреНрдпрд╛ рдШрдЯрдХ рдЕрднреА рднреА рдЖрд░реЛрд╣рд┐рдд рд╣реИ рдЬрдм рд╣рдореЗрдВ рд╡рд╛рджрд╛ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИ, рд╣рдореЗрдВ рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдЬрд╛рджреВ рдХрд╛ рд╕рд╣рд╛рд░рд╛ рд▓реЗрдирд╛ рдкрдбрд╝рддрд╛ рд╣реИ рддрд╛рдХрд┐ рд╣рдо рдЙрд╕ рдШрдЯрдХ рд╕реЗ рдЕрдкрдиреЗ рд╡рд╛рджреЗ рдХреЛ "рдЕрдирдмрд╛рдЗрдВрдб" рдХрд░ рд╕рдХреЗрдВ, рдЬрд┐рд╕рдореЗрдВ рдЗрд╕рдХрд╛ рдкрд░рд┐рдгрд╛рдо рд╕реЗрдЯ рдХрд░рдирд╛ рд╣реИ, рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╡рд╛рджреЗ рдХреЗ рдЦрд┐рд▓рд╛рдл рд▓рдбрд╝рдирд╛ рддреИрдпрд╛рд░ рдХрд┐рдпреЗ рдЧрдП рд╣реИрдВред
рдореЗрд░реЗ рд▓рд┐рдП рдпрд╣ рдПрдХ рд╕рдорд╛рдзрд╛рди рдХреА рдЕрдзрд┐рдХрддрд╛ рдХреА рддрд░рд╣ рд▓рдЧрддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдкрд░реАрдХреНрд╖рдг рдЗрд╕рдХрд╛ рдЦреНрдпрд╛рд▓ рд░рдЦрдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рд╣реИред

рд╣рдо рдХреЗрд╡рд▓ рдирд┐рдореНрди рджреНрд╡рд╛рд░рд╛ рд╕рд░рд▓ рдЬрд╛рдБрдЪ рд░рдЦ рд╕рдХрддреЗ рд╣реИрдВ:

React.createClass(function() {
  componentDidMount: function() {
    this._isMounted = true;

    ajax(/* */).then(this.handleResponse);
  }

  handleResponse: function(response) {
    if (!this._isMounted) return; // Protection

    /* */
  }

  componentWillUnmount: function() {
    this._isMounted = false;
  }
});

рдпрд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдореЗрд░реА рд░рд╛рдп рд╣реИ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдПрдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдШрдЯрдХ рдХреЗ рдЕрдВрджрд░ рдПрдХ рд╡рд╛рджреЗ рдХреЗ рд╕рд╛рде async рдбреЗрдЯрд╛ рд▓реЛрдб рдХрд░рдирд╛ рдПрдХ рдРрд╕рд╛ рд╕рд╛рдорд╛рдиреНрдп рдкрд░рд┐рджреГрд╢реНрдп рд╣реИ рдХрд┐ рдЗрд╕реЗ рд╣рдорд╛рд░реЗ рдЕрдкрдиреЗ рдмреЙрдпрд▓рд░рдкреНрд▓реЗрдЯ рдХреЛрдб рдХреЛ рд▓рд┐рдЦрдиреЗ рдХреЗ рдмрдЬрд╛рдп рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреНрд╡рд╛рд░рд╛ рдХрд╡рд░ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдорд╛рдЙрдВрдЯ рд╕реНрдерд┐рддрд┐ рдХреЛ рдЧрд┐рд░рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ рд╢реНрд░реЛрддрд╛ рдХреЛ рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛ рдЬрдм рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкреНрд░рддреНрдпреЗрдХ рдШрдЯрдХ рдореЗрдВ рдбреАрдУрдПрдо рдорд╛рдЙрдВрдЯ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕рдорд╛рдкреНрдд рдХрд░ рджреЗрдЧреА (рд╡рд╣реА, рдЬреЛ рдШрдЯрдХрдбрд┐рдбрдорд╛рдЙрдВрдЯ рд╕рдВрд▓рдЧреНрди рдХрд░рддреА рд╣реИ, рдпрджрд┐ рдкрд░рд┐рднрд╛рд╖рд┐рдд рд╣реИ), рд▓реЗрдХрд┐рди рдпрд╣ рдкреВрд░реНрдг рдкрд░ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░реЗрдЧреА, рдХреНрдпреЛрдВрдХрд┐ рд╣рдореЗрдВ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ рдЗрд╕реЗ рд╣рд░ рдЬрдЧрд╣ рдЧрд┐рд░рд╛рдиреЗ рдХреЗ рд▓рд┐рдПред рдШрдЯрдХ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рддреИрдпрд╛рд░ рдбреЛрдо рдорд╛рдЙрдВрдЯ рдХреЛ рдирд╣реАрдВ рд╕реБрдирддреЗ рдХреНрдпреЛрдВрдХрд┐ рдХреЙрдореНрдкреЛрдиреЗрдВрдЯрдбрд┐рдбрдорд╛рдЙрдВрдЯ рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рд╣реИред

рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ setState рдХреЛ рдПрдХ рдЬрдВрдЬреАрд░ рд╡рд╛рджрд╛ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рд╡рд╛рдВрдЫрд┐рдд рд░рд╛рдЬреНрдп рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЛ рд╣рд▓ рдХрд░рддрд╛ рд╣реИ? рдпрджрд┐ рдШрдЯрдХ рдЕрдирдорд╛рдЙрдВрдЯ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдпрджрд┐ рдХреЛрдИ рд▓рдВрдмрд┐рдд рд╡рд╛рджреЗ рд╣реИрдВ рддреЛ рдЙрдирдХреЗ рдЕрдВрддрд┐рдо рдкрд░рд┐рдгрд╛рдо рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

@istarkov рдЕрдЪреНрдЫрд╛ рдкреИрдЯрд░реНрди, рдЗрд╕реЗ рдкрд╕рдВрдж рд╣реИ! рдпрд╣рд╛рдБ рдЗрд╕рдХреЗ рд▓рд┐рдП рдереЛрдбрд╝рд╛ рдмрджрд▓рд╛ рд╣реБрдЖ рдПрдкреАрдЖрдИ рд╣реИ:

// create a new promise
const [response, cancel] = await cancelable(fetch('/api/data'));

// cancel it
cancel();

рдЪреВрдВрдХрд┐ рдореИрдВ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдФрд░ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдирдпрд╛ рд╣реВрдВ, рдмрд╕ рдЗрд╕реЗ рд╡рд╣рд╛рдВ рдлреЗрдВрдХрдиреЗ рдХреЗ рд▓рд┐рдП: рдЕрдЬрд╛рдХреНрд╕ рдЯрд┐рдк рдХреЗ .isMounted() рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╡реЗрдмрд╕рд╛рдЗрдЯ рд╡реЗрдмрд╕рд╛рдЗрдЯ рд╕реЗ рдЕрд╕рд╣рдордд рд╣реИред componentWillUnmount рдореЗрдВ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд▓реЛрдб рдХреЛ рд░рджреНрдж рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рдкреВрд░реНрдг рдпреБрдХреНрддрд┐ рджреЗрдЦрдирд╛ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛, рд╢рд╛рдпрдж рдЙрдкрд░реЛрдХреНрдд @istarkov рдХреЗ рдкреИрдЯрд░реНрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ред

@dtertman https://github.com/facebook/react/pull/5870 рдореЗрдВ рдлрд┐рдХреНрд╕реНрдб рд╣реИ, рдЬрдм рдбреЙрдХреНрд╕ рдЪреЗрд░реА-рдкрд┐рдХ рдУрд╡рд░ рд╣реЛ рдЬрд╛рдПрдВрдЧреЗ рддреЛ рдСрдирд▓рд╛рдЗрди рд╣реЛрдВрдЧреЗред

@jimfb рдзрдиреНрдпрд╡рд╛рдж, рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рдЗрд╕реЗ рдЦреЛрдЬ рдореЗрдВ рдХреИрд╕реЗ рдпрд╛рдж рдХрд┐рдпрд╛ред

@istarkov рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдЬрд╛рдирдмреВрдЭрдХрд░ рдерд╛ рд▓реЗрдХрд┐рди рдореВрд▓ рд╡рд╛рджрд╛ рд╡рд┐рдлрд▓ рд╣реЛрдиреЗ рдкрд░ рдЖрдкрдХрд╛ makeCancelable рд╕рдВрднрд╛рд▓ рдирд╣реАрдВ рдкрд╛рддрд╛ рд╣реИред рдЬрдм рдореВрд▓ рд╡рд╛рджрд╛ рдЦрд╛рд░рд┐рдЬ рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдХреЛрдИ рд╣реИрдВрдбрд▓рд░ рдирд╣реАрдВ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдпрд╣ рдЖрджрд░реНрд╢ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХреНрдпреЛрдВрдХрд┐ рдЖрдк рдЕрднреА рднреА рдореВрд▓ рд╡рд╛рджреЗ рдкрд░ рдПрдХ рддреНрд░реБрдЯрд┐ рдХреЛ рд╕рдВрднрд╛рд▓рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред

рдпрд╣рд╛рдБ рдПрдХ makeCancelable рд▓рд┐рдП рдореЗрд░рд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рд╣реИ рдЬреЛ рдореВрд▓ рд╡рд╛рджреЗ рдореЗрдВ рдЕрд╕реНрд╡реАрдХреГрддрд┐ рдХреЛ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИ:

const makeCancelable = (promise) => {
  let hasCanceled_ = false;

  const wrappedPromise = new Promise((resolve, reject) => {
    promise.then((val) =>
      hasCanceled_ ? reject({isCanceled: true}) : resolve(val)
    );
    promise.catch((error) =>
      hasCanceled_ ? reject({isCanceled: true}) : reject(error)
    );
  });

  return {
    promise: wrappedPromise,
    cancel() {
      hasCanceled_ = true;
    },
  };
};

рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдореИрдВ рдХрд╣рд╛рдВ рдЦрдбрд╝рд╛ рд╣реВрдВ рдЕрдЧрд░ рд░рджреНрдж рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╡рд╛рджреЗ рдХрд░рдирд╛ рдПрдХ рдЕрдЪреНрдЫрд╛ рд╡рд┐рдЪрд╛рд░ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдЧрд░ рд╣рдо рд╡рд╛рджреЗ рд░рджреНрдж рдХрд░рдиреЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рд╕рдВрд░рдХреНрд╖рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП :)ред

@vpontis : +1:

@istarkov рдЖрдкрдХреА рдореВрд▓ рдкреЛрд╕реНрдЯ рдпрд╣рд╛рдБ рд╕рдВрджрд░реНрднрд┐рдд рд╣реИ: https://facebook.github.io/react/blog/2015/12/16/ismounted-antipattern.html

рдЕрдкрдиреА рдкреЛрд╕реНрдЯ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдпрд╛ рдХреНрдпрд╛ рдореБрдЭреЗ рдкреЛрд╕реНрдЯ рдХреЗ рд▓реЗрдЦрдХ рдХреЛ рд╕рдВрджреЗрд╢ рджреЗрдирд╛ рдЪрд╛рд╣рд┐рдП?

@vpontis рдзрдиреНрдпрд╡рд╛рдж, рдореИрдВ рдареАрдХ рдХрд░ рджреВрдВрдЧрд╛! (https://github.com/facebook/react/pull/6152)

рдЕрд░реЗ @jimfb , рдЗрдВрдЯрд░рдиреЗрдЯ рдкрд░ рдЖрдкрдХрд╛ рдордЬрд╝рд╛рдХ рдЙрдбрд╝рд╛рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ!

makeCancelable рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдПрдХ рдФрд░ рдмрдЧ рдлрд┐рдХреНрд╕: рдпрд╣ рд╣рд╛рд▓ рдХреЗ рдиреЛрдб рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдореЗрдВ UnhandledPromiseRejectionWarning рдХрд╛ рдХрд╛рд░рдг рдмрди рд╕рдХрддрд╛ рд╣реИ (рд╡рд┐рд╢реЗрд╖рдХрд░ рдЬрдм рдиреЛрдб рдХреЗ рдирдП рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд╕рд╛рде рдкрд░реАрдХреНрд╖рдг рдЪрд▓ рд░рд╣рд╛ рд╣реЛ)ред рдиреЛрдб 6.6.0 рдореЗрдВ рд╣реБрдП рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдпрд╣ рд╣реИ рдХрд┐ рд╕рднреА рдЕрдирд╣реЗрд▓реНрдб рд╡рд╛рджреЛрдВ рдХреЗ рдЕрд╕реНрд╡реАрдХрд░рдг рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдПрдХ рдЪреЗрддрд╛рд╡рдиреА рд╣реЛрддреА рд╣реИред @vpontis рдХреЗ рдореМрдЬреВрджрд╛ рдХреЛрдб рдореЗрдВ рдЕрд▓рдЧ-рдЕрд▓рдЧ then рдФрд░ catch рдХреЙрд▓ рдПрдХ рд╣реА рдореВрд▓ рд╡рд╛рджреЗ рдкрд░ рдереЗред рдкреНрд░рднрд╛рд╡реА рд░реВрдк рд╕реЗ, рдпрд╣ _рджреЛ_ рд╡рд╛рджреЗ рдмрдирд╛рддрд╛ рд╣реИ, рдПрдХ рдЬреЛ рдХреЗрд╡рд▓ рд╕рдлрд▓рддрд╛ рдХреЛ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИ, рдФрд░ рдПрдХ рдЬреЛ рдХреЗрд╡рд▓ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИред рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдпрджрд┐ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рд╣реИ, рддреЛ рдиреЛрдб рджреНрд╡рд╛рд░рд╛ рдкрд╣рд▓реЗ рд╡рд╛рджреЗ рдХреЛ рдПрдХ рдЕрдирд╣реЗрд▓реНрдб рд╡рд╛рджрд╛ рдЕрд╕реНрд╡реАрдХреГрддрд┐ рдХреЗ рд░реВрдк рдореЗрдВ рджреЗрдЦрд╛ рдЬрд╛рдПрдЧрд╛ред

рдлрд┐рдХреНрд╕ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИ: рдмрд╕ рджреЛ рдХреЙрд▓реЛрдВ рдХреЛ рдЪреЗрди рдХрд░реЗрдВ рддрд╛рдХрд┐ рдпрд╣ рдПрдХ рд╕рдлрд▓рддрд╛ рдФрд░ рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд░ рджреЛрдиреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рд╡рд╛рджрд╛ рдХрд░реЗред рдпрд╣рд╛рдБ рдирд┐рд╢реНрдЪрд┐рдд рдХреЛрдб рд╣реИ:

const makeCancelable = (promise) => {
  let hasCanceled_ = false;

  const wrappedPromise = new Promise((resolve, reject) => {
    promise
      .then((val) =>
        hasCanceled_ ? reject({isCanceled: true}) : resolve(val)
      )
      .catch((error) =>
        hasCanceled_ ? reject({isCanceled: true}) : reject(error)
      );
  });

  return {
    promise: wrappedPromise,
    cancel() {
      hasCanceled_ = true;
    },
  };
};

@alangpierce рдпрд╣ рд╕рд╣реА рдХреЗ рдмрд╣реБрдд рдХрд░реАрдм рд╣реИ, рд▓реЗрдХрд┐рди рдХрд╛рдлреА рдирд╣реАрдВ; рдпрджрд┐ resolve() рдпрд╛ reject() рдХрд┐рд╕реА рднреА рдХрд╛рд░рдг рд╕реЗ рдПрдХ рд╣рд▓ рдХрд┐рдП рдЧрдП рд╡рд╛рджреЗ рдкрд░ рд╕рдордХрд╛рд▓рд┐рдХ рд░реВрдк рд╕реЗ рдлреЗрдВрдХрддрд╛ рд╣реИ, рддреЛ рджреЛрдиреЛрдВ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рд╕рдорд╛рдзрд╛рди .then(onFulfilled, onRejected) рдкреИрдЯрд░реНрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИ:

const makeCancelable = (promise) => {
  let hasCanceled_ = false;

  const wrappedPromise = new Promise((resolve, reject) => {
    promise.then(
      (val) => hasCanceled_ ? reject({isCanceled: true}) : resolve(val),
      (error) => hasCanceled_ ? reject({isCanceled: true}) : reject(error)
    );
  });

  return {
    promise: wrappedPromise,
    cancel() {
      hasCanceled_ = true;
    },
  };
};

рдХреНрдпрд╛ рдпрд╣ рдкреНрд░рднрд╛рд╡реА рд░реВрдк рд╕реЗ рд░рджреНрдж рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╕рдорд╛рдзрд╛рди рдирд╣реАрдВ рд╣реИ, рд╡рд╣реА isMounted() рдХреЙрд▓ рд╣реИ рдЬрдм рдмрд┐рдВрджреБ 3 рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП рдХрд┐ isMounted() рдХреЛ рдмрд╣рд┐рд╖реНрдХреГрдд рдХреНрдпреЛрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

рдПрдХ рдШрдЯрдХ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрдирдорд╛рдЙрдВрдЯ рд╣реЛрдиреЗ рдкрд░ рд╕реЗрдЯрд╕реНрдЯреЗрдЯ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ред
рдпрд╣ рдПрдХ рдордЬрдмреВрдд рд╕рдВрдХреЗрдд рд╣реИ рдХрд┐ рдПрдХ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдХреЙрд▓рдмреИрдХ рдареАрдХ рд╕реЗ рд╕рд╛рдл рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдореБрдЦреНрдпрдзрд╛рд░рд╛ рдХреЗ рдЬреЗрдПрд╕ рдПрдкреАрдЖрдИ рд╣реИрдВрдЧрд┐рдВрдЧ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдХреЙрд▓рдмреИрдХ рдХреЛ рд╕рд╛рдл рдХрд░рдиреЗ рд╕реЗ рдмрдЪрдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рдмрдирд╛рддрд╛ рд╣реИред

рдПрдХ рдХреЙрд▓рдмреИрдХ рдХреЛрдИ рдмрдбрд╝реА рдмрд╛рдд рдирд╣реАрдВ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╡рд╣ рдХреЙрд▓рдмреИрдХ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдФрд░ рдЗрдВрдЯрд░рдореАрдбрд┐рдПрдЯ рдХреЙрд▓рдмреИрдХ, рд╡рд╛рджреЗ рдФрд░ рд╕рдмреНрд╕рдХреНрд░рд┐рдкреНрд╢рди рдкрд░ рд▓рдЯрдХрддрд╛ рд╣реИред рдпрджрд┐ рдЖрдкрдХреЗ рдмрд╣реБрдд рд╕реЗ рдШрдЯрдХ рдРрд╕рд╛ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдЬрд▓реНрджреА рд╕реЗ рд╕реНрдореГрддрд┐ рд╕рдорд╕реНрдпрд╛рдУрдВ рдореЗрдВ рднрд╛рдЧ рд▓реЗрдВрдЧреЗ

makeCancellable рдмрд╕ рдПрдХ рдФрд░ рд╡рд╛рджрд╛ рдмрдирд╛рддрд╛ рд╣реИ рдЬреЛ рдШрдЯрдХ рдХреЗ рд╕рдВрджрд░реНрдн рд╡рд╛рд▓реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рд╕рдорд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИред рдореЗрдХ рдХреИрдВрд╕реЗрд▓реЗрдмрд▓ рд╕рдорд╛рдзрд╛рди рд╕рд┐рд░реНрдл рдмреВрд▓рд┐рдпрди рд╕рдВрдкрддреНрддрд┐ рдХреЛ рд╡рд╛рджреЗ рдореЗрдВ рд▓реЗ рдЬрд╛ рд░рд╣рд╛ рд╣реИред

рдЬреАрд╕реА рдореБрджреНрджреЗ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рд░рджреНрдж рдХрд░рдиреЗ() рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдкрд░ рдХреБрдЫ рд░рджреНрдж рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЕрдиреНрдпрдерд╛ рдЖрдкрдХреЗ рдкрд╛рд╕ рдЕрднреА рднреА рдПрд╕рд┐рдВрдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕реЗ рдШрдЯрдХ рддрдХ рдПрдХ рд╕рдВрджрд░реНрдн рд╢реНрд░реГрдВрдЦрд▓рд╛ рд╣реИред

class CancellableDeferred {
  constructor(request) {
    this.deferred = $.Deferred();

    request.then((data) => {
      if (this.deferred != null) {
        this.deferred.resolve(data);
      }
    });

    request.fail((data) => {
      if (this.deferred != null) {
        this.deferred.reject(data);
      }
    });
  }

  cancel() {
    this.deferred = null;
  } 

  promise() {
    return this.deferred.promise();
  }
}

-> рдпрд╣ рд╣реИ рдХрд┐ рдореИрдВ рдЗрд╕реЗ jQuery рдЖрд╕реНрдердЧрд┐рдд рд╡рд╕реНрддреБрдУрдВ рдХреЗ рд╕рд╛рде рдХреИрд╕реЗ рдХрд░реВрдВрдЧрд╛ред рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдкреНрд░реЙрдорд┐рд╕ рдПрдкреАрдЖрдИ рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рдирд╣реАрдВ рд╣реВрдВ рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ рдпрд╣ рдХреИрд╕рд╛ рджрд┐рдЦреЗрдЧрд╛ред рд╕рд╛рде рд╣реА, рдпрд╣ рд╕реНрдердЧрд┐рдд рдХреЛ рдЕрд╕реНрд╡реАрдХрд╛рд░ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдЬрдм рд░рджреНрдж() рдХреЛ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ рд╕реНрдердЧрд┐рдд рдХреЛ рд╣рд▓ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рд╢рд╛рдпрдж, рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЗрд╕ рдкрд░ рд▓реЛрдЧреЛрдВ рдХреА рдЕрд▓рдЧ рд░рд╛рдп рд╣реИред

рддреЛ рдЪреЗрди рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддреА рд╣реИ:

AJAX рдЕрдиреБрд░реЛрдз -> рдмрдВрдж -> CancellableDeferredInstance -> JQuery рд╕реНрдердЧрд┐рдд -> рдШрдЯрдХ

рдлрд┐рд░ рд░рджреНрдж рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рдРрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИ:

AJAX рдЕрдиреБрд░реЛрдз -> рдмрдВрдж -> рд░рджреНрдж рдХрд░рдиреЗ рдпреЛрдЧреНрдпDeferredInstance/рд╡рд╕реНрддреБ рд╕рдВрджрд░реНрдн рдЕрдм рд╢реВрдиреНрдп/JQuery рд╕реНрдердЧрд┐рдд -> рдШрдЯрдХ

рдЗрд╕рд▓рд┐рдП AJAX рдЕрдиреБрд░реЛрдз рдЕрдм рдШрдЯрдХ рдХреЛ GCd рд╣реЛрдиреЗ рд╕реЗ рдирд╣реАрдВ рд░реЛрдХ рд░рд╣рд╛ рд╣реИ [рдпрд╣ рдорд╛рдирддреЗ рд╣реБрдП рдХрд┐ рдореИрдВрдиреЗ рдЧрд▓рддреА рд╕реЗ рд╕реНрдердЧрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрджрд░реНрдн рдзрд╛рд░рдг рдХрд░рдХреЗ рдХрд╣реАрдВ рднреА рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдЦрд░рд╛рдм рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИред рдпрд╛рдп рдмрдВрдж ....]

рд╣рд╛рдп @benmmurphy , рдореИрдВ рдЬреЗрдПрд╕ рдХрдЪрд░рд╛ рд╕рдВрдХрд▓рди рд╕реЗ рд╕реБрдкрд░ рдкрд░рд┐рдЪрд┐рдд рдирд╣реАрдВ рд╣реВрдВ рдФрд░ рдпрд╣ рд░рд┐рдПрдХреНрдЯ рдХреЗ рд╕рд╛рде рдЕрд▓рдЧ рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдПрдХ рдЕрд▓рдЧ рд╕рдордЭ рд╣реИред

makeCancellable рдПрдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдШрдЯрдХ рдХреЛ рдЕрдирдорд╛рдЙрдВрдЯ рд╣реЛрдиреЗ рдкрд░ рдХрдЪрд░рд╛ рдПрдХрддреНрд░ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдореИрдВ рд╕рдордЭрд╛рддрд╛ рд╣реВрдБред

makeCancellable рдмрд╕ рдПрдХ рдФрд░ рд╡рд╛рджрд╛ рдмрдирд╛рддрд╛ рд╣реИ рдЬреЛ рдШрдЯрдХ рдХреЗ рд╕рдВрджрд░реНрдн рд╡рд╛рд▓реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рд╕рдорд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИред рдореЗрдХ рдХреИрдВрд╕реЗрд▓реЗрдмрд▓ рд╕рдорд╛рдзрд╛рди рд╕рд┐рд░реНрдл рдмреВрд▓рд┐рдпрди рд╕рдВрдкрддреНрддрд┐ рдХреЛ рд╡рд╛рджреЗ рдореЗрдВ рд▓реЗ рдЬрд╛ рд░рд╣рд╛ рд╣реИред

рдмрд┐рдирд╛ makeCancellable :

handleError() {
  if (this.isMounted()) {
    console.log('ERROR')
  }
}

makeCancellable :

promise.then(...).fail((reason) => {
  if (reason.isCancelled) return;
  console.log('ERROR');
})

makeCancellable рдмрд┐рдирд╛ рдЖрдкрдХреЗ рдкрд╛рд╕ рдЕрднреА рднреА this рд╕рдВрджрд░реНрдн рд╣реИ,

@vpontis

рдореЗрд░реЗ рдкрд╛рд╕ рдХреБрдЫ рдиреЛрдбрдЬ рдХреЛрдб рд╣реИ рдЬреЛ рд╕рдорд╕реНрдпрд╛ рдХреЛ рджрд┐рдЦрд╛рддрд╛ рд╣реИред рдПрдХ рдмрд╛рд░ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдХреЙрд▓рдмреИрдХ resolve рдХреЛ рд╢реВрдиреНрдп рдкрд░ рд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж Foo рдШрдЯрдХ рдХреЗрд╡рд▓ GC'd рд╣реЛрдЧрд╛ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдорд╛рди рд▓реЗрдВ рдХрд┐ рдЖрдк рдПрдХ рдЕрдЬрд╛рдХреНрд╕ рдЕрдиреБрд░реЛрдз рдХреЛ рдмрдВрдж рдХрд░ рджреЗрддреЗ рд╣реИрдВ рдЬрд┐рд╕реЗ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ 30s рд▓рдЧрддреЗ рд╣реИрдВ рддреЛ рдШрдЯрдХ рдЕрдирдорд╛рдЙрдВрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рддрдм рдШрдЯрдХ 30 рдХреЗ рд▓рд┐рдП GCd рдирд╣реАрдВ рд╣реЛрдЧрд╛ред рдпрд╣ рдЙрди рд╕рдорд╕реНрдпрд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ рдЬрд┐рдиреНрд╣реЗрдВ рд╡реЗ isMount() рдкрджрд╛рд╡рдирдд рдХрд░рдиреЗ рдХреЗ рд╕рд╛рде рд╣рд▓ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд░рд╣реЗ рд╣реИрдВред

npm install promise
npm install weak

node --expose-gc gc.js
first gc Foo {}
after first gc Foo {}
after resolve = null Foo {}
foo gc'd
after second gc {}

https://gist.github.com/benmmurphy/aaf35a44a6e8a1fbae1764ebed9917b6

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ:

рдЖрдкрд╕реЗ рдмрд╛рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЦреЗрдж рд╣реИ, рд▓реЗрдХрд┐рди рдкрд╣рд▓реА рдмрд╛рд░ рдЬрдм рдореИрдВрдиреЗ рдкреЛрд╕реНрдЯ рдкрдврд╝реА рддреЛ рдореБрдЭреЗ рд╡рд╣ рдмрд╛рдд рд╕рдордЭ рдореЗрдВ рдирд╣реАрдВ рдЖрдИ рдЬрд┐рд╕реЗ рдЖрдк рдмрдирд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣реЗ рдереЗ, рд▓реЗрдХрд┐рди рдЕрдм рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореИрдВ рдХрд░рддрд╛ рд╣реВрдВред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдЬреЛ рдХрд╣рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рд╡рд╣ рдпрд╣ рд╣реИ рдХрд┐ рддреНрд░реБрдЯрд┐ рдХреЙрд▓рдмреИрдХ рдореЗрдВ рдШрдЯрдХ рдХрд╛ рд╕рдВрджрд░реНрдн рдирд╣реАрдВ рд╣реИ (рдпрд╛ рдШрдЯрдХ рдХреЗ рд╕рдВрджрд░реНрдн рдХрд╛ рдкрд╛рд▓рди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ) рддреЛ рдШрдЯрдХ рдХреЛ рд╡рд╛рджреЗ рджреНрд╡рд╛рд░рд╛ рд╕рдВрджрд░реНрднрд┐рдд рдирд╣реАрдВ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕рдЪ рд╣реИред рд╡реИрд╕реЗ рдкрд╣рд▓рд╛ рднрд╛рдЧ рд╕рддреНрдп рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЗрд╕ рддрд░реНрдХ рдореЗрдВ рд╕рдорд╕реНрдпрд╛рдПрдБ рд╣реИрдВ:

1) рднрд▓реЗ рд╣реА рдЖрдкрдХреЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд░ рдореЗрдВ рдШрдЯрдХ рдХрд╛ рд╕рдВрджрд░реНрдн рди рд╣реЛ, then() рдХреЙрд▓рдмреИрдХ рдЖрдорддреМрд░ рдкрд░ рд╣реЛрдЧрд╛ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП then рд╣реИрдВрдбрд▓ рдЖрдорддреМрд░ рдкрд░ this.setState(...) ред
2) рднрд▓реЗ рд╣реА рдЖрдкрдХреЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд░ рдореЗрдВ рдЙрд╕ рдШрдЯрдХ рдХрд╛ рд╕рдВрджрд░реНрдн рди рд╣реЛ рдЬреЛ рдЕрдзрд┐рдХрд╛рдВрд╢ рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд░ рдХрд░реЗрдВрдЧреЗред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рд╡реЗ рдХреБрдЫ рдРрд╕рд╛ рдХрд░реЗрдВрдЧреЗ:

promise.then(...).fail((reason) => {
  if (reason.isCancelled) return;
  console.log('ERROR');

  this.setState({error: true});
})

3) рднрд▓реЗ рд╣реА рд╣рдо рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдХреЛрдб then() рдХреЙрд▓рдмреИрдХ рдХрд╛ рдкрд╛рд▓рди рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ рдФрд░ рд╣рдо рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ isCancelled рдЪрд░ рдХреА рдЬрд╛рдВрдЪ рдХреЗ рдмрд╛рдж рдлрд╝рдВрдХреНрд╢рди рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓ рдЬрд╛рдПрдЧрд╛, рдЬреАрд╕реА рдХреЛ рдпрд╣ рдирд╣реАрдВ рдкрддрд╛ рд╣реИред

рдФрд░ рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рдХреЛрдИ рдореЗрд░реЗ рдЙрджрд╛рд╣рд░рдг рдпрд╛ рдЙрд╕рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдХрд┐рд╕реА рдЪреАрдЬрд╝ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗ, рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рдЖрдк рдкрд░реАрдХреНрд╖рдг рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ GCs рд╕рд╣реА рд╣реИред рдореИрдВрдиреЗ рдЕрднреА рддрдХ рдореЗрд░рд╛ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИ рдФрд░ рдЕрдЧрд░ рдпрд╣ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рддреЛ рдореБрдЭреЗ рдЖрд╢реНрдЪрд░реНрдп рдирд╣реАрдВ рд╣реЛрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рдореИрдВрдиреЗ рдХреБрдЫ рдореВрд░реНрдЦрддрд╛рдкреВрд░реНрдг рддреНрд░реБрдЯрд┐ рдХреА рд╣реИ: /

рд╡рд╛рджрд╛ рдПрдкреАрдЖрдИ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдЬреАрд╕реА рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдиреЛрдбрдЬ рдореЗрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдореИрдВ рдмрдВрдж рд╣реЛрдиреЗ рдХреЗ рдкрд╛рд╕ _resolve , _reject рдкреИрд░рд╛рдореНрд╕ рдирд╣реАрдВ рд░рдЦрдирд╛ рдкрд╕рдВрдж рдХрд░реВрдВрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдЬреЗрдПрд╕ рд╕реНрдкреЗрдХ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЧрд╛рд░рдВрдЯреА рд╣реИ рдпрд╛ рдпрджрд┐ рдпрд╣ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реЛрддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдиреЛрдб рдХреБрдЫ рдЕрдиреБрдХреВрд▓рди рдХрд░ рд░рд╣рд╛ рд╣реИред рдХреНрдпрд╛ рдХреЛрдИ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рджреГрд╢реНрдпрдорд╛рди рд╕рднреА рдЪрд░ рдпрд╛ рдХреЗрд╡рд▓ рд╡реЗрд░рд┐рдПрдмрд▓ рдХреЛ рдХреИрдкреНрдЪрд░ рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдЬрд┐рдиреНрд╣реЗрдВ рдмрдВрдж рдХрд░рдиреЗ рдореЗрдВ рд╕рдВрджрд░реНрднрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ? рдореБрдЭреЗ рдкрддрд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдХреЛрдИ рд╡реНрдпрдХреНрддрд┐ рдЬреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЬреЗрдПрд╕ рдХреЛ рд╕рдордЭрддрд╛ рд╣реИ рд╡рд╣ рдЭрдВрдХрд╛рд░ рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рд╕рдордЭрд╛ рд╕рдХрддрд╛ рд╣реИ :)

var makeCancelable = (promise) => {
  let resolve;
  let reject;

  const wrappedPromise = new Promise((_resolve, _reject) => {
    resolve = _resolve;
    reject = _reject;

    promise.then((val) => {
       if (resolve != null) resolve(val)
    });
    promise.catch((error) => {
       if (reject != null) reject(error)
    });
  });

  return {
    promise: wrappedPromise,
    cancel() {
      resolve = null;
      reject = null;
    },
  };
};

рдХреНрдпрд╛ рдорд╛рдЙрдВрдЯреЗрдб рдлрд╝рдВрдХреНрд╢рди рдХреЛ 16.0 рдореЗрдВ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛?

@Istarkov рдХреЛрдб рдХреЗ рд╕рд╛рде рдЫреЛрдЯреЗ рд╕реБрдзрд╛рд░ рдХреЗ рд▓рд┐рдП рд╕реБрдЭрд╛рд╡:

const makeCancelable = (promise) => {
    let hasCanceled_ = false
    promise.then((val) =>
        hasCanceled_ ? reject({isCanceled: true}) : resolve(val)
    )
    .catch((error) =>
        hasCanceled_ ? reject({isCanceled: true}) : reject(error)
    )

    return {
        promise,
        cancel() {
            hasCanceled_ = true
        }
    }
}

рдмрд╛рдд рдмрд╕ рдЗрддрдиреА рд╕реА рд╣реИ рдХрд┐ рдирдпрд╛ рд╡рд╛рджрд╛ рдмреЗрдорд╛рдиреА рд╣реИред

рдмрд╛рдд рдмрд╕ рдЗрддрдиреА рд╕реА рд╣реИ рдХрд┐ рдирдпрд╛ рд╡рд╛рджрд╛ рдмреЗрдорд╛рдиреА рд╣реИред

@BnayaZil рдЖрдк resolve рдФрд░ reject рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХреЛ рдХреЙрд▓ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ рдХрд┐ рд╡реЗ рдХрд╣рд╛рдВ рд╕реЗ рд╣реИрдВред рдХреНрдпрд╛ рдЖрдкрдХрд╛ рдорддрд▓рдм Promise.resolve рдФрд░ Promise.reject ? рдЙрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдЖрдк рдЕрднреА рднреА рдПрдХ рдирдпрд╛ рд╡рд╛рджрд╛ рд╡рд╛рдкрд╕ рдХрд░ рд░рд╣реЗ рд╣реЛрдВрдЧреЗред

рдХреБрдЫ рджрд┐рдиреЛрдВ рдкрд╣рд▓реЗ DOM рд╡рд┐рдирд┐рд░реНрджреЗрд╢рди рдореЗрдВ рдПрдХ рдирдпрд╛ API рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рдерд╛ рдЬреЛ рдЖрдкрдХреЛ fetch() рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рдирд┐рд░рд╕реНрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдпрд╣ рдПрдкреАрдЖрдИ рдЕрднреА рддрдХ рдХрд┐рд╕реА рднреА рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рдкреЙрд▓реАрдлрд┐рд▓ рдмрдирд╛рдпрд╛ рд╣реИ рдЬреЛ рдПрдирдкреАрдПрдо рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реИ "abortcontroller-polyfill"ред рдкреЙрд▓реАрдлрд┐рд▓ рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ

рд╡рд┐рд╡рд░рдг рдпрд╣рд╛рдБ:
https://mo.github.io/2017/07/24/abort-fetch-abortcontroller-polyfill.html

рдЪреВрдВрдХрд┐ React.createClass рдЕрдм рд░рд┐рдПрдХреНрдЯ 16 рдореЗрдВ рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИ рдФрд░ рдирдП create-react-class рдкреИрдХреЗрдЬ рдореЗрдВ isMounted рд▓рд┐рдП рдПрдХ рд╕реНрдкрд╖реНрдЯ рдмрд╣рд┐рд╖реНрдХрд░рдг рд╕рдВрджреЗрд╢ рд╢рд╛рдорд┐рд▓ рд╣реИ, рдореИрдВ рдЗрд╕реЗ рдмрдВрдж рдХрд░рдиреЗ рдЬрд╛ рд░рд╣рд╛ рд╣реВрдВред

рдореИрдВ @benmmurphy рд╕реЗ рд╕рд╣рдордд @istarkov рдХрд╛ рд╕рдорд╛рдзрд╛рди рдкреНрд░рднрд╛рд╡реА рд░реВрдк рд╕реЗ isMounted() рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдЬреИрд╕рд╛ рд╣реА рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдХрдЪрд░рд╛ рд╕рдВрдЧреНрд░рд╣рдг рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рдорд╛рдзрд╛рди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред

@benmmurphy рдХрд╛ рд╕рдорд╛рдзрд╛рди рдХрд░реАрдм рд╣реИ рд▓реЗрдХрд┐рди рдЧрд▓рдд рдЪрд░ рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдХреБрдВрдЬреА рдмрдВрдж рдХрд░рдиреЗ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдкрд╛рд╕ рдХрд░ рд░рд╣реА рд╣реИ рдЬреЛ рд╣реИрдВрдбрд▓рд░ рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рддреА рд╣реИ:

const makeCancelable = promise => {
  let cancel = () => {};

  const wrappedPromise = new Promise((resolve, reject) => {
    cancel = () => {
      resolve = null;
      reject = null;
    };

    promise.then(
      val => {
        if (resolve) resolve(val);
      },
      error => {
        if (reject) reject(error);
      }
    );
  });

  wrappedPromise.cancel = cancel;
  return wrappedPromise;
};

рдЗрд╕ рд╕рдорд╛рдзрд╛рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдФрд░ рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рдХрд┐ рдпрд╣ рд╕рдорд╛рдзрд╛рди рдХрдЪрд░рд╛ рд╕рдВрдЧреНрд░рд╣рдг рдХреА рдЕрдиреБрдорддрд┐ рдХреНрдпреЛрдВ рджреЗрддрд╛ рд╣реИ рдФрд░ рдкрд┐рдЫрд▓реЗ рд╕рдорд╛рдзрд╛рди рдпрд╣рд╛рдВ рдирд╣реАрдВ рдорд┐рд▓ рд╕рдХрддреЗ

рдореИрдВрдиреЗ рдЖрдЧреЗ рдмрдврд╝рдХрд░ рдЗрд╕реЗ npm рдкреИрдХреЗрдЬ рдореЗрдВ рдмрджрд▓ рджрд┐рдпрд╛, рдЯреНрд░реИрд╢реЗрдмрд▓-рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рдЙрдиреНрд╣реЗрдВ рд░рджреНрдж рдХрд░ рджреЗрддрд╛ рд╣реИред

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдореЗрд░рд╛ рдмреБрд░рд╛, рдореИрдВрдиреЗ рдЕрднреА @hjylevis рдереНрд░реИрд╢реЗрдмрд▓ рдХреЛ рджреЗрдЦрд╛, рдФрд░ рдпрд╣ рд╡рд╛рджреЛрдВ рдХреЛ рднреА рд░рджреНрдж рдХрд░рддрд╛ рд╣реИред рдлрд┐рд░ рднреА рдиреАрдЪреЗ рджрд┐рдпрд╛ рдЧрдпрд╛ рдкреИрдЯрд░реНрди рдЖрдИрдПрдордУ рдПрдХ рдЫреЛрдЯрд╛ рд╕рд╛ рд╕реБрдзрд╛рд░ рд╣реИред

рдЗрдирдореЗрдВ рд╕реЗ рдХреЛрдИ рднреА рд╕рдорд╛рдзрд╛рди рд╡рд╛рджреЗ рдХреЛ

function makeCancelable(promise) {
  let active = true;
  return {
    cancel() {active = false},
    promise: promise.then(
      value => active ? value : new Promise(()=>{}),
      reason => active ? reason : new Promise(()=>{})
    )
  }
}

// used as above:

const {promise, cancel} = makeCancelable(Promise.resolve("Hey!"))

promise.then((v) => console.log(v)) // never logs
cancel()

рдпрд╣рд╛рдВ рд░рд╣рддреЗ рд╣реИрдВ

рдЬреАрд╕реА рдФрд░ рдХреЙрдлреА рдХреЗ рд╕рдВрдмрдВрдз рдореЗрдВ рдЕрднреА рддрдХ рд▓реЛрд╣реЗ рдХреЗ рд▓рд┐рдП рд╕реВрдХреНрд╖реНрдорддрд╛рдПрдВ рд╣реЛ рд╕рдХрддреА рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдкреИрдЯрд░реНрди рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рд▓реМрдЯрд╛рдпрд╛ рдЧрдпрд╛ рд╡рд╛рджрд╛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд░рджреНрдж рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рд░рд┐рд╕рд╛рд╡ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ (рдореИрдВрдиреЗ рдЗрд╕реЗ рдЕрддреАрдд рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рд╣реИ)ред

@pygy рдЙрддреНрддрд░ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж!

рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдЖрдкрдХрд╛ рд╕рдорд╛рдзрд╛рди рдЕрднреА рднреА рдХрдЪрд░рд╛ рд╕рдВрдЧреНрд░рд╣рдг рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИред рдЖрдкрдиреЗ рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ @istarkov рдХреЗ рд╕рдорд╛рдзрд╛рди рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрд╛ рд╣реИ рдЬреЛ рдПрдХ рд╕рд╢рд░реНрдд рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред

рдЖрдк рдЗрд╕ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдЯреНрд░реИрд╢реЗрдмрд▓ рдореЗрдВ

рдЖрдкрдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рднреА рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдареАрдХ рд╕реЗ рд╕рдВрднрд╛рд▓рдиреЗ рдореЗрдВ рд╡рд┐рдлрд▓ рд░рд╣рддрд╛ рд╣реИред

рдпрд╣ 2018 рд╣реИ рдХреНрдпрд╛ рдКрдкрд░ рдмрддрд╛рдП рдЧрдП рд╕реЗ рднреА рдмреЗрд╣рддрд░ рддрд░реАрдХрд╛ рд╣реИ?

рд╣рд╛рдВ, рдЖрдк рдХреБрдЫ рдиреЗрд╡рд┐рдЧреЗрд╢рди рдврд╛рдВрдЪреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рдирдХреЗ рдкрд╛рд╕ рдореВрд▓ рдирд┐рд╡рд╛рд╕реА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЗ рдЖрдХрд╛рд░ рд╕реЗ рджреЛрдЧреБрдирд╛ рджрд╕реНрддрд╛рд╡реЗрдЬ рд╣реИ рд▓реЗрдХрд┐рди рдпрд╣ рдмрд╣реБрдд рд╣реА рдкреЗрд╢реЗрд╡рд░ рд╣реИ

рдПрдХ рд╡рд╛рджрд╛ "рд░рджреНрдж" рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдпреЗ рд╕реНрдирд┐рдкреЗрдЯ рдорд╣рд╛рди IMHO рдирд╣реАрдВ рд╣реИрдВред рд░рджреНрдж рдХрд┐рдП рдЧрдП рд╡рд╛рджреЗ рддрдм рднреА рд╣рд▓ рдирд╣реАрдВ рд╣реЛрдВрдЧреЗ рдЬрдм рддрдХ рдХрд┐ рдореВрд▓ рд╡рд╛рджрд╛ рд╣рд▓ рдирд╣реАрдВ рд╣реЛ рдЬрд╛рддрд╛ред рддреЛ рдореЗрдореЛрд░реА рдХреНрд▓реАрдирдЕрдк рддрдм рддрдХ рдирд╣реАрдВ рд╣реЛрдЧрд╛ рдЬрдм рддрдХ рдХрд┐ рдЖрдк рд╕рд┐рд░реНрдл рдПрдХ рдорд╛рдЙрдВрдЯреЗрдб рдЯреНрд░рд┐рдХ рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдирд╣реАрдВ рдХрд░рддреЗред

рдПрдХ рдЙрдЪрд┐рдд рд░рджреНрдж рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╡рд╛рджрд╛ рд░реИрдкрд░ рдХреЛ рджреВрд╕рд░реЗ рд╡рд╛рджреЗ рдФрд░ Promise.race рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдпрд╛рдиреА Promise.race([originalPromise, cancelationPromise])

@benmmurphy рдХрд╛ рд╕рдорд╛рдзрд╛рди рдХрд░реАрдм рд╣реИ рд▓реЗрдХрд┐рди рдЧрд▓рдд рдЪрд░ рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореЗрд░рд╛ рд╕рдорд╛рдзрд╛рди рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдкрд░реНрдпрд╛рдкреНрдд рдЬрд╛рдирдХрд╛рд░реА рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд░рдирдЯрд╛рдЗрдо рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдХреНрдпрд╛ рд╡рд╛рджрд╛ рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдЖрдк рдЕрдкрдиреЗ рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рдиреЛрдб рдХреЗ рддрд╣рдд рд╕рдорд╛рдзрд╛рди рдЪрд▓рд╛рддреЗ рд╣реИрдВ рддреЛ рдпрд╣ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдЬреАрд╕реА рдореВрд▓реНрдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдореЗрд░реЗ рд╕рдорд╛рдзрд╛рди рдиреЗ рд╕рдВрдХрд▓реНрдк/рдЕрд╕реНрд╡реАрдХрд╛рд░ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдЙрдЪреНрдЪ рджрд╛рдпрд░реЗ рдореЗрдВ рдЕрд╕рд╛рдЗрди рдХрд┐рдпрд╛ рдФрд░ рдлрд┐рд░ рд░рджреНрдж рдХрд┐рдП рдЬрд╛рдиреЗ рдкрд░ рдЗрди рдорд╛рдиреЛрдВ рдХреЛ рд╣рдЯрд╛ рджрд┐рдпрд╛ред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдлрд╝рдВрдХреНрд╢рдВрд╕ рдЕрднреА рднреА рдирд┐рдЪрд▓реЗ рджрд╛рдпрд░реЗ рдореЗрдВ рдЙрдкрд▓рдмреНрдз рдереЗ рд▓реЗрдХрд┐рди рд╕рдВрджрд░реНрднрд┐рдд рдирд╣реАрдВ рдереЗред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдзреБрдирд┐рдХ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЗрдВрдЬрди рдмрдВрдж рд╣реЛрдиреЗ рддрдХ рдЪрд░ рдХреЛ рдХреИрдкреНрдЪрд░ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ рдЬрдм рддрдХ рдХрд┐ рдЙрдиреНрд╣реЗрдВ рд╕рдВрджрд░реНрднрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдмрдбрд╝реА рд╕рдорд╕реНрдпрд╛ рд╣реБрдЖ рдХрд░рддреА рдереА рдЬрд╣рд╛рдВ рд▓реЛрдЧ рдЧрд▓рддреА рд╕реЗ рдбреЛрдо рд▓реАрдХ рдмрдирд╛ рд▓реЗрддреЗ рдереЗ рдХреНрдпреЛрдВрдХрд┐ рдЙрдиреНрд╣реЛрдВрдиреЗ рд╕рд╛рдорд╛рди рдХрд┐рдпрд╛ рдерд╛: var element = findDOM (); element.addEventListener ('рдХреНрд▓рд┐рдХ', рдлрд╝рдВрдХреНрд╢рди() {}); рдФрд░ рддрддреНрд╡ рдХреЛ рдмрдВрдж рдХрд░рдиреЗ рдореЗрдВ рд╕рдВрджрд░реНрднрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рднрд▓реЗ рд╣реА рдЗрд╕реЗ рдмрдВрдж рдХрд░рдиреЗ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реЛред

@hjylewis @benmmurphy рд╣рдореЗрдВ рд╣реИрдВрдбрд▓рд░реНрд╕ рдХреЛ рд╣рдЯрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИ ?? рд╕рдВрдЪрд╛рд▓рдХреЛрдВ рдХреЗ рдЙрддреНрд╕рд╛рд╣рд┐рдд рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж, рдХрдЪрд░рд╛ рд╕рдВрдЧреНрд░рд╣рдг рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рд╣реЛрддрд╛ рд╣реИ, рд╣реИ рдирд╛ ??

рдПрдХ рд╡рд╛рджрд╛ "рд░рджреНрдж" рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдпреЗ рд╕реНрдирд┐рдкреЗрдЯ рдорд╣рд╛рди IMHO рдирд╣реАрдВ рд╣реИрдВред рд░рджреНрдж рдХрд┐рдП рдЧрдП рд╡рд╛рджреЗ рддрдм рднреА рд╣рд▓ рдирд╣реАрдВ рд╣реЛрдВрдЧреЗ рдЬрдм рддрдХ рдХрд┐ рдореВрд▓ рд╡рд╛рджрд╛ рд╣рд▓ рдирд╣реАрдВ рд╣реЛ рдЬрд╛рддрд╛ред рддреЛ рдореЗрдореЛрд░реА рдХреНрд▓реАрдирдЕрдк рддрдм рддрдХ рдирд╣реАрдВ рд╣реЛрдЧрд╛ рдЬрдм рддрдХ рдХрд┐ рдЖрдк рд╕рд┐рд░реНрдл рдПрдХ рдорд╛рдЙрдВрдЯреЗрдб рдЯреНрд░рд┐рдХ рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдирд╣реАрдВ рдХрд░рддреЗред

рдПрдХ рдЙрдЪрд┐рдд рд░рджреНрдж рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╡рд╛рджрд╛ рд░реИрдкрд░ рдХреЛ рджреВрд╕рд░реЗ рд╡рд╛рджреЗ рдФрд░ Promise.race рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдпрд╛рдиреА Promise.race([originalPromise, cancelationPromise])

@hjylewis рдФрд░ рдореЗрд░рд╛ рдХреНрдпрд╛ рдЖрдк рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ рдЖрдк рдЗрд╕реЗ рдХрдордЬреЛрд░ рдиреЛрдб рдХреЗ рд╕рд╛рде рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдЙрдиреНрд╣реЗрдВ рдлрд┐рд░ рд╕реЗ рджреЗрдЦрдХрд░ рдореИрдВ рд╕рд╣рдордд рд╣реВрдВ рдХрд┐ рдЙрдирдореЗрдВ рд╕реЗ рдХреЛрдИ рднреА рдореВрд░реНрдЦрддрд╛рдкреВрд░реНрдг рд▓рд┐рдЦрд┐рдд рд╡рд╛рджрд╛ рдХреЛрдб рдирд╣реАрдВ рд╣реИред рдПрдХ рд╡рд╛рджрд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдЖрдк рд╕рдВрднрд╛рд╡рд┐рдд рд░реВрдк рд╕реЗ рдЕрд╕реНрд╡реАрдХрд╛рд░ рдХрд┐рдП рдЧрдП рд░рд╛рдЬреНрдп рдореЗрдВ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП 'рд░рджреНрдж' рд╡рд╛рджреЗ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░реЗрдВрдЧреЗ рдФрд░ рдЙрдирдореЗрдВ рд╕реЗ рдХреЛрдИ рднреА рдРрд╕рд╛ рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╕рдВрднрд╡рддрдГ рдПрдХ рдШрдЯрдХ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдпрд╣ рдПрдХ рдРрд╕рд╛ рд╕рдорд╛рдзрд╛рди рд╣реИ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реЛрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдХреЛ рдЕрд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрддрд┐рд░рд┐рдХреНрдд рдХреЛрдб рд▓рд┐рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдПрдХ рдореВрд░реНрдЦрддрд╛рдкреВрд░реНрдг рдЕрд╕реНрд╡реАрдХрд╛рд░реНрдп рд╡рд╛рджрд╛ рдПрдХ рд░рджреНрдж рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╡рд╛рджрд╛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП Promise.race([]) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдЧрд╛ред рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЬрдм рдХреЛрдИ рд╡рд╛рджрд╛ рд╣рд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рд▓рдВрдмрд┐рдд рдХреЙрд▓рдмреИрдХ рд╣рдЯрд╛ рджрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЙрд╕ рдмрд┐рдВрджреБ рдкрд░ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдиреЗрдЯрд╡рд░реНрдХ рд╕реЗ рдЖрдкрдХреЗ рдШрдЯрдХ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рд╕рдВрджрд░реНрдн рд╢реНрд░реГрдВрдЦрд▓рд╛ рдирд╣реАрдВ рд╣реЛрдЧреА рдХреНрдпреЛрдВрдХрд┐ рдЕрдм рд░реЗрд╕ рд╡рд╛рджреЗ рдФрд░ рдШрдЯрдХ рдХреЗ рдмреАрдЪ рдХреЛрдИ рд╕рдВрджрд░реНрдн рдирд╣реАрдВ рд╣реЛрдЧрд╛ред

рдореБрдЭреЗ рдЙрддреНрд╕реБрдХрддрд╛ рд╣реИ рдХрд┐ рдЕрдЧрд░ рдХрд┐рд╕реА рддрд░рд╣ рд╕реЗ рдЙрди рд░рджреНрдж рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╡рд╛рджреЛрдВ рдХреЗ рд╕рд╛рде Promise.all() рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ рдФрд░ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХрдВрд╕реЛрд▓ рдореЗрдВ рдЕрдирдХрд╣реА рддреНрд░реБрдЯрд┐рдпреЛрдВ рд╕реЗ рдмрдЪрдирд╛ рд╣реИ ...

рдпрд╣ 2018 рд╣реИ рдХреНрдпрд╛ рдКрдкрд░ рдмрддрд╛рдП рдЧрдП рд╕реЗ рднреА рдмреЗрд╣рддрд░ рддрд░реАрдХрд╛ рд╣реИ?

рдХрд┐рд╕реА рд╡рд╛рджреЗ рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЛ рд░рджреНрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдмреЗрд╣рддрд░ рддрд░реАрдХрд╛ рдпрд╛рдиреА, рд╕реЗрдЯрдЯрд╛рдЗрдордЖрдЙрдЯ, рдПрдкреАрдЖрдИ рдХреЙрд▓ рдЖрджрд┐ред рдпрд╣ 2019 рд╣реИ

рдЯреАрд╕реА39 рдкрд░ рдкреНрд░реЙрдорд┐рд╕ рдХреИрдВрд╕рд┐рд▓реЗрд╢рди рдереНрд░реЗрдб рдЪрд▓ рд░рд╣рд╛ рд╣реИ, (рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ) рдпрд╣ рдпрд╣рд╛рдВ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХрддрд╛ рдХрд╛ рд╣реИ (рд╢рд╛рдпрдж .. рдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ)
https://github.com/tc39/proposal-cancellation/issues/24

рдХрд┐рд╕реА рд╡рд╛рджреЗ рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЛ рд░рджреНрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдмреЗрд╣рддрд░ рддрд░реАрдХрд╛ рдпрд╛рдиреА, рд╕реЗрдЯрдЯрд╛рдЗрдордЖрдЙрдЯ, рдПрдкреАрдЖрдИ рдХреЙрд▓ рдЖрджрд┐ред рдпрд╣ 2019 рд╣реИ

рдХреНрдпрд╛ рд╣рдо рдХреБрдЫ рдРрд╕рд╛ рдвреВрдВрдв рд░рд╣реЗ рд╣реИрдВ

const promise = new Promise(r => setTimeout(r, 1000))
  .then(() => console.log('resolved'))
  .catch(()=> console.log('error'))
  .canceled(() => console.log('canceled'));

// Cancel promise
promise.cancel();
рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

MoOx picture MoOx  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

UnbearableBear picture UnbearableBear  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

jimfb picture jimfb  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

framerate picture framerate  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

zpao picture zpao  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ