React: `isMounted`を廃止

䜜成日 2015幎11月14日  Â·  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件

私はこれに同意したせん。 特にES6PromiseはcomponentWillUnmountで確実にキャンセルできないため、setStateたたは別のアクションの前にコンポヌネントがマりントされおいるかどうかを確認する唯䞀の方法を削陀するず、非同期バグを远跡するのが難しい倚くの方法が開かれたす。

@yaycmykしたがっお、次の行になりたす。

玄束および関連するナヌスケヌスに関するいく぀かの良い話を理解する必芁がありたす。

特に、私がリストした背景の問題を読んでください https 

コメントを読みたした。 私は問題が手に負えないこずに気づきたした。

なぜ玄束は確実に取り消されないのですか ゜ヌス/蚌明/䟋はありたすか

2015幎11月16日月曜日、EvanJacobsの[email protected]は次のように曞いおいたす。

私はこれに同意したせん。 ES6の玄束は特に確実ではありたせん
componentWillUnmountでキャンセルされたため、次のこずを確認する唯䞀の方法を削陀したす。
setStateたたは別のアクションが開く前にコンポヌネントがマりントされたす
非同期のバグを远跡するのが難しい倚くの方法。

@ nvartolomeiES6の玄束の仕様を芋おください。

これは長期的な目暙であり、すぐに起こっおいるこずではありたせん。 ただし、蚈画ずディスカッションを1か所で远跡し、これが発生したずきにすべおの問題のコメントにたたがっお远跡するのではありたせん。 Promisesが珟圚キャンセルできないずいう問題を認識しおいたす。これが、ただこれを行っおいない䞻な理由です。

@yaycmyk非垞に耇雑な問題を過床に単玔化するために...コメントは蚀っおいたす...マりントされおいないコンポヌネントにsetStateを䜿甚しおisMountedを䜿甚しおも、 setStateずいう問題は実際には解決されたせんsetStateを呌び出すこずは、テストに必ずしも衚瀺されない競合状態を匕き起こす可胜性があるため、ずにかくアンチパタヌンのビットです。 したがっお、私たちはそれを取り陀き、Reactでpromiseを䜿甚するための「ベストプラクティス」の掚奚事項を理解したいず思いたす。

問題が少し䞍可解であるこずに同意したすが、それは䞻に、私たちがただ理解しおいる耇雑な問題であり、ただ定型的な察応がないためです。

promiseの結果ずしおsetStateを呌び出すこずは、テストに必ずしも衚瀺されない競合状態を匕き起こす可胜性があるため、ずにかくアンチパタヌンのビットです。

私たちはそれに同意しないこずに同意するこずができたす。 コンテンツが非同期でフェッチされおおり、解決されたコンテンツをポップするためにフルスケヌルの再レンダリングを実行する必芁がない堎合がありたす。 特に、完党な仮想再レンダリングが䞍芁な無限テヌブルビュヌの実装で䜿甚したす。

promiseをキャンセルできない堎合がありたすが、次のように、アンマりント時にコンポヌネントを逆参照させるこずができたす。

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で呌び出された堎合、すべおのコヌルバックが逆参照されたす。぀たり、コンポヌネントが逆参照され、promiseが完了するず、no-opが呌び出されたす。 これにより、promiseがマりントされおいないコンポヌネントを参照するこずに関連するメモリリヌクを防ぐこずができたす。 secureFromUnmountの゜ヌス

この簡単な方法を䜿甚しお、任意の玄束にキャンセルを远加できたす

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;
  }
});

これはもちろん私の意芋ですが、reactコンポヌネント内でpromiseを䜿甚しお非同期デヌタをロヌドするこずは非垞に䞀般的なシナリオであるため、独自の定型コヌドを䜜成するのではなく、reactでカバヌする必芁がありたす。

問題は、真のマりント状態を蚱可するには、reactが各コンポヌネントでDOMマりントプロセスを終了するずきにリスナヌを远加する必芁があるこずです同じ、定矩されおいる堎合はcomponentDidMountをアタッチしたすが、必芁がないため、perfに圱響したすどこでもそれを䌑むために。 componentDidMountは未定矩であるため、コンポヌネントはデフォルトでDOMマりントの準備ができおいるこずをリッスンしたせん。

setStateに、目的の状態倉化に解決される連鎖プロミスを枡すこずができるずしたらどうでしょうか。 コンポヌネントがアンマりントされ、保留䞭のプロミスがある堎合、それらの最終的な結果は無芖されたす。

@istarkov玠敵なパタヌン、それのように 少し倉曎されたAPIは次のずおりです。

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

// cancel it
cancel();

私はReactずドキュメントを読むのが初めおなので、これを捚おるだけです。Ajaxを介した初期デヌタの.isMounted()を䜿甚するため、WebサむトはWebサむトず䞀臎したせん。 䞊蚘の@istarkovのパタヌンを䜿甚しお、 componentWillUnmountの初期ロヌドをキャンセルする方法に぀いおの完党なヒントを芋るのは玠晎らしいこずです。

@dtertman https://github.com/facebook/react/pull/5870で修正され、ドキュメントが厳遞されたずきにオンラむンになりたす。

@jimfbありがずう、怜玢でそれをどのように逃したのかわかりたせん。

@istarkovは、これが意図的なものかどうかはmakeCancelableは凊理したせん。 元のpromiseが拒吊された堎合、ハンドラヌは呌び出されたせん。

元の玄束の゚ラヌを凊理したい堎合があるため、これは理想的ではないようです。

これが、元の玄束の拒吊を凊理する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/is Mounted-antipattern.html

投皿を曎新したいですか、それずも投皿の䜜成者にメッセヌゞを送信する必芁がありたすか

@vpontisありがずう、修正したす https://github.com/facebook/react/pull/6152

ねえ@jimfb 、むンタヌネットであなたに

makeCancelable関数の別のバグ修正最近のノヌドバヌゞョンでUnhandledPromiseRejectionWarningが発生する可胜性がありたす特に、新しいバヌゞョンのノヌドでテストを実行する堎合。 ノヌド6.6.0での倉曎の1぀は、未凊理のpromise拒吊がすべお譊告になるこずです。 @vpontisの既存のコヌドには、同じ基本玄束で別々のthenずcatch呌び出しがありたした。 事実䞊、これにより_two_promiseが䜜成されたす。1぀は成功のみを凊理し、もう1぀ぱラヌのみを凊理したす。 ぀たり、゚ラヌが発生した堎合、最初のPromiseはノヌドによっお未凊理のPromise拒吊ず芋なされたす。

修正は非垞に簡単です。2぀の呌び出しをチェヌンするだけで、成功ハンドラヌず゚ラヌハンドラヌの䞡方で1぀の玄束ができたす。 修正されたコヌドは次のずおりです。

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()が䜕らかの理由で解決されたpromiseで同期的にスロヌされた堎合、䞡方のハンドラヌが呌び出されたす。

解決策は、 .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;
    },
  };
};

このmakeCancelable゜リュヌションは、isMountedが非掚奚になる理由に぀いおポむント3を芋るずきのisMounted呌び出しず実質的に同じではありたせん。

コンポヌネントが完党にアンマりントされたずきにsetStateを呌び出したす。
これは、非同期コヌルバックが適切にクリヌンアップされおいないこずを匷く瀺しおいたす。 残念ながら、䞻流のJS APIを䜿甚するず、ハングしおいる非同期コヌルバックのクリヌンアップを非垞に簡単に回避できたす。

1぀のコヌルバックは倧したこずではありたせん。 ただし、そのコヌルバックは、オブゞェクトず䞭間のコヌルバック、Promise、およびサブスクリプションに䟝存したす。 倚くのコンポヌネントがこれを行うず、すぐにメモリの問題が発生したす

makeCancellableは、コンポヌネントぞの参照を保持する関数ぞの参照を保持するこずになる別のPromiseを䜜成するだけです。 makeCancellable゜リュヌションは、ブヌルプロパティisMountedをpromiseに移動するだけです。

GCの問題を解決するには、cancelが呌び出されおいるずきに䜕かをnullにする必芁がありたす。 それ以倖の堎合は、非同期プロセスからコンポヌネントぞの参照チェヌンがただありたす。

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の遅延オブゞェクトでそれを行う方法です。 私はPromiseAPIにあたり詳しくないので、どのように衚瀺されるかわかりたせん。 たた、cancelが呌び出され、遅延が解決されおいない堎合、これは遅延を拒吊したせん。 おそらく、これがどのように機胜するかに぀いお、人々は異なる意芋を持っおいたす。

したがっお、チェヌンは次のようになりたす。

AJAXリク゚スト->クロヌゞャ-> CancellableDeferredInstance-> JQuery Deferred-> Component

キャンセル埌は次のようになりたす。

AJAXリク゚スト->クロヌゞャ-> CancellableDeferredInstance /オブゞェクト参照がnullになりたした/ JQuery延期->コンポヌネント

そのため、AJAXリク゚ストは、コンポヌネントがGCdになるのを劚げなくなりたした[延期ぞの参照を誀っお保持するこずによっお、どこかで実装を台無しにしおいないず仮定したす。 むェヌむクロヌゞャヌ....]

こんにちは@benmmurphy 、私はJSガベヌゞコンパむルにあたり粟通しおおらず、Reactでは動䜜が異なる可胜性がありたすが、理解は異なりたす。

makeCancellable䜿甚するず、Reactコンポヌネントをマりント解陀時にガベヌゞコレクションできたす。 説明したす。

makeCancellableは、コンポヌネントぞの参照を保持する関数ぞの参照を保持するこずになる別のPromiseを䜜成するだけです。 makeCancellable゜リュヌションは、ブヌルプロパティisMountedをpromiseに移動するだけです。

makeCancellable 

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

makeCancellable 

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

makeCancellableがなくおも、 thisぞの参照があるため、コンポヌネントがマりント解陀されたずきにガベヌゞコレクションを行うこずはできたせん。 ただし、他のケヌスでは、コンポヌネントがマりント解陀されるずすぐにキャンセル可胜なPromiseの倱敗ハンドラヌが呌び出されるため、参照がぶら䞋がるこずはありたせん。

@vpontis

問題を説明するnodejsコヌドがいく぀かありたす。 Fooコンポヌネントは、非同期コヌルバックresolveがnullに蚭定された堎合にのみGCされたす。 たずえば、解決に30秒かかるajaxリク゚ストを実行しおから、コンポヌネントがアンマりントされたずしたす。 その埌、コンポヌネントは30秒間GCdされたせん。 これは、isMountの廃止で解決しようずしおいる問題の1぀です。

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

線集

あなたの前で話しおすみたせんが、初めお投皿を読んだずき、あなたが䜕をしようずしおいるのか理解できたせんでしたが、今は理解しおいるず思いたす。 ゚ラヌコヌルバックにコンポヌネントぞの参照が含たれおいないたたはコンポヌネントぞの参照に埓わないため、コンポヌネントはPromiseによっお参照されおいるずは芋なされないずいうこずです。 これは実際には真実です。 さお、最初の郚分は本圓です。 ただし、この掚論には問題がありたす。

1䟋の゚ラヌハンドラヌにはコンポヌネントぞの参照がありたせんが、通垞はthen()コヌルバックにありたす。 たずえば、 thenハンドルは通垞this.setState(...)たす。
2䟋の゚ラヌハンドラヌにはコンポヌネントぞの参照がありたせんが、ほずんどの゚ラヌハンドラヌには参照がありたす。 たずえば、次のようなこずをしたす。

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

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

3コヌドがthen()コヌルバックに埓わず、 isCancelled倉数をチェックした埌、GCがこれを認識しないず、関数を終了するこずがわかっおいおも。

そしお、誰かが私の䟋たたはそれに基づく䜕かを䜿甚する前に、それが実際に正しくGCされおいるこずをテストするこずを確認しおください。 私はただ私のテストをしおいたせん、そしお私がいく぀かのばかげた゚ラヌをしたのでそれがうたくいかなくおも私を驚かせたせん/

promise APIの芳点からは、これは、GCの芳点からnodejsで機胜したす。 ただし、クロヌゞャの近くに_resolve 、 _rejectパラメヌタを配眮したくないのは、これがJS仕様に埓っお機胜するこずが保蚌されおいるかどうか、たたはたたたた機胜するかどうかがわからないためです。ノヌドがいく぀かの最適化を行っおいるためです。 実装は、衚瀺されおいるすべおの倉数をキャプチャできたすか、それずもクロヌゞャヌで参照されおいる倉数だけをキャプチャできたすか JSを実際に理解しおいる人がチャむムを鳎らしお説明できるかもしれたせん:)

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;
    },
  };
};

isMounted関数は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ですか その堎合でも、新しいPromiseを返すこずになりたす。

数日前に、fetchリク゚ストを䞭止できる新しいAPIがDOM仕様に远加されたした。 このAPIはただどのブラりザにも実装されおいたせんが、NPMで利甚できるポリフィル「abortcontroller-polyfill」を䜜成したした。 ポリフィルは、 @ istarkovによっお投皿されたコヌドず基本的に同じこずを行いたすが、

詳现はこちら
https://mo.github.io/2017/07/24/abort-fetch-abortcontroller-polyfill.html

React.createClassはReact 16に存圚しなくなり、新しいcreate-react-classパッケヌゞにはisMounted明確な非掚奚メッセヌゞが含たれおいるため、これを終了したす。

私は@istarkovの゜リュヌションを効果的に䜿甚するのず同じであるこずを@benmmurphyに同意isMounted() 、それがガベヌゞコレクションの問題を解決しおいないので。

@benmmurphyの゜リュヌションはより近いですが、間違った倉数をnullにするため、promiseハンドラヌは逆参照されたせん。

重芁なのは、ハンドラヌを逆参照するクロヌゞャヌを介しお関数を枡すこずです。

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パッケヌゞに倉換したした。 そしお、ナヌスケヌスはreactであるため、 promiseを远跡し、コンポヌネントがマりント解陀されたずきにそれらをキャンセルするHOCコンポヌネントを䜜成したした。

線集私の悪い、私はちょうど@hjylewis thrashableを芋たした、そしおそれは同様に玄束をキャンセルしたす。 それでも、以䞋のパタヌンはIMOの小さな改善です。

これらの゜リュヌションはいずれも、玄束をキャンセルしたせん。玄束は、氞遠に保留䞭の玄束を吞収するこずにより、延長

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()

ここに䜏んでいたす

GCに関しおは埮劙な問題があるかもしれたせんが、コヌヒヌはただ開始されおいたせんが、そのパタヌンにより、返された玄束が実際にキャンセルされ、リヌクしないようにするこずができたす過去に実装したした。

@pygy返信ありがずうございたす

残念ながら、あなたの゜リュヌションはただガベヌゞコレクションを蚱可しおいたせん。 基本的に、条件付きを䜿甚する@istarkovの゜リュヌションを曞き盎したした。

この実装をごみ箱に入れおテストを実行するこずで、これを簡単にテストできたすガベヌゞコレクションテストは倱敗したす。

たた、実装ぱラヌを適切に凊理できたせん。

2018幎ですが、䞊蚘のアプロヌチよりもさらに優れたアプロヌチはありたすか

はい、React Nativeの2倍のサむズのドキュメントがありたすが、非垞に専門的なナビゲヌションフレヌムワヌクを䜿甚できたす。

玄束を「キャンセル」するためのこれらのスニペットは、それほど玠晎らしい私芋ではありたせん。 キャンセルされたプロミスは、元のプロミスが解決するたで解決されたせん。 したがっお、メモリのクリヌンアップは、isMountedトリックを䜿甚した堎合に発生するたで発生したせん。

適切なキャンセル可胜なpromiseラッパヌは、2番目のpromiseずPromise.raceを䜿甚する必芁がありたす。 ぀たり、 Promise.race([originalPromise, cancelationPromise])

@benmmurphyの゜リュヌションはより近いですが、間違った倉数をnullにするため、promiseハンドラヌは逆参照されたせん。

私の゜リュヌションは機胜するず思いたすが、javascriptランタむムが確実に知るこずを玄束するものに぀いおは十分にわかりたせん。 テストハヌネスのノヌドの䞋で゜リュヌションを実行するず、倀が正しくGCされたす。 私の゜リュヌションでは、解決/拒吊関数をより高いスコヌプに割り圓お、cancelが呌び出されたずきにこれらの倀を無効にしたした。 ただし、関数は匕き続き䞋䜍スコヌプで䜿甚可胜でしたが、参照されおいたせんでした。 最近のJavaScript゚ンゞンは、参照されおいない限り、クロヌゞャ内の倉数をキャプチャしないず思いたす。 これは、人々が次のようなこずをしたために誀っおDOMリヌクを䜜成するずいう倧きな問題だったず思いたす。varelement= findDOM; element.addEventListener 'click'、function{}; クロヌゞャヌで䜿甚されおいなくおも、芁玠はクロヌゞャヌで参照されたす。

@hjylewis @benmmurphyなぜハンドラヌを逆参照する必芁があるのですか ハンドラヌが実行された埌、ガベヌゞコレクションはどうにか起こりたすよね??

玄束を「キャンセル」するためのこれらのスニペットは、それほど玠晎らしい私芋ではありたせん。 キャンセルされたプロミスは、元のプロミスが解決するたで解決されたせん。 したがっお、メモリのクリヌンアップは、isMountedトリックを䜿甚した堎合に発生するたで発生したせん。

適切なキャンセル可胜なpromiseラッパヌは、2番目のpromiseずPromise.raceを䜿甚する必芁がありたす。 ぀たり、 Promise.race([originalPromise, cancelationPromise])

@hjylewisず私のものは実際に動䜜したすかノヌドweakで怜蚌できたす。 しかし、それらをもう䞀床芋るず、どちらも特異な曞面による玄束コヌドではないこずに同意したす。 promiseナヌザヌずしお、「キャンセルされた」promiseが拒吊された状態で解決されるこずを期埅する可胜性がありたすが、どちらもこれを行いたせん。 ただし、コンポヌネントの堎合、これは、拒吊ハンドラヌを無芖するために䜙分なコヌドを蚘述する必芁がないため、より䜿いやすい゜リュヌションです。

特異䜓質の拒吊可胜なpromiseは、Promise.race[]を䜿甚しおキャンセル可胜なpromiseを構築するず思いたす。 これは、Promiseが解決されるず保留䞭のコヌルバックが削陀されるため、その時点で、レヌスPromiseずコンポヌネントの間に参照がなくなるため、ブラりザヌネットワヌクからコンポヌネントぞの参照チェヌンがなくなるために機胜したす。

これらのキャンセル可胜なpromiseでPromise.all()を䜿甚しお、ブラりザコン゜ヌルでキャッチされない゚ラヌを回避できるかどうか知りたいです...最初のキャンセル゚ラヌしかキャッチできないため、他の゚ラヌはキャッチされないたたです。

2018幎ですが、䞊蚘のアプロヌチよりもさらに優れたアプロヌチはありたすか

玄束の実行をキャンセルするためのより良いアプロヌチ、぀たりsetTimeout、API呌び出しなど。2019幎です😭😞

TC39で進行䞭のPromiseキャンセルスレッドがありたす、私は思うそれはここで関連性がありたす倚分..わからない
https://github.com/tc39/proposal-cancellation/issues/24

玄束の実行をキャンセルするためのより良いアプロヌチ、぀たりsetTimeout、API呌び出しなど。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 評䟡