Promise の実装アイデアの詳細な分析 (コード例)

不言
リリース: 2018-11-24 14:09:22
転載
1904 人が閲覧しました

この記事では、Promise の実装アイデア (コード例) について詳しく説明します。必要な方は参考にしていただければ幸いです。

Promise の実装アイデアについての個人的な理解

Promise は便利だけど、書き方がとても奇妙で、人の考え方が理解できないと常々感じていました。 Promise を実装する人は考えます。

しかし、最近Promise導入の思考プロセスについて個人的に少し理解できたので、ここに書いておきます。

この記事では私のアイデアをまだ明確に説明できていないような気がするので、このプロセスを後でより明確に表現するために記録として扱います。

ユースケース

   var p1 = new Promise2( ( resolve, reject ) => {
            setTimeout( () => {
                resolve( 'hello' )
            }, 1000 )

        } )

        p1.then( res => {
                console.log( res + 'world' )
                return res + 'world'
            } )
            .then( res => {
                console.log( res + 'ziwei' )
                return res + 'ziwei'
            } )
ログイン後にコピー

関数の実装はコンポーネントのカプセル化に似ていると思います。まず、次の点を考慮してください。

  • 1 .この機能は何に使われるのでしょうか?

  • 2. 受け入れられるパラメータは何ですか?

  • 次に、例とこれらの質問を組み合わせると、

1.

Promise は非同期プロセス制御に使用されます。
    平たく言うと、特定の関数が一時的に実行されないことを望みますが、それを実行したい場合は、それを解決して関数が実行されるようにします。
  • 2.

    コンストラクター Promise は関数を受け入れます。
  • 関数のパラメータは、resolve、reject、resolve、reject です。これらもユーザーによって呼び出されます。ユーザーが次の非同期実行を希望する場合は、resolve(0
  • #) を呼び出します。 ## 3.Promise インスタンスを返す

    各 Promise インスタンスには then メソッドがあり、その then メソッドは新しい Promise インスタンスも返すため、連鎖内で then を呼び出すことができます。
  • #最初に Promise を実装します (then のチェーン呼び出しは実装されていません)

  • 1. Promise は、他のものに関係なく fn を受け入れます。この fn はどうなると思いますか?内部的に do が呼び出されるので、方法はわかりませんが、最初に fn(resolve,reject)
    2 を呼び出します。その後、この解決と拒否はユーザーによって実装されません。したがって、それらは Promise またはimplement によって開発される必要があります。次に、resolve と拒否を実装する必要があります。これらは、状態を変更するために使用される必要があるため、this.state
  • # を定義します。 ##3.resolve と拒否はユーザーのパラメータも受け入れます。その後、then メソッドが呼び出されるときに、このパラメータを
  • ## で渡す必要があります。

    #4.then は、successFn と errorFn を受け入れます。この 2 つの関数は、一時的に実行したくないのですが、どうすればよいでしょうか。2 つの配列を宣言し、最初に保存して、

  •         class Promise2 {
                constructor( fn ) {
                    this.successFnArray = []  // 用来缓存successFn和errorFn
                    this.errorFnArray = []
                    this.state = 'pendding'
                    const resolve = ( res ) => {      // resolve就做2件事情  1: 修改状态 2:调用successFn
                        this.state = 'fulfilled'
                        this.value = res         // this.value用来缓存data数据或者error
    
                        this.successFnArray.forEach( successFn => {
                            successFn( res )
                        } )
                    }
                    const reject = ( err ) => {
                        this.state = 'rejected'
                        this.value = err
    
                        this.errorFnArray.forEach( errorFn => {
                            errorFn( res )
                        } )
                    }
                    fn( resolve, reject )   // 先调用fn再说
                }
    
                then( successFn, errorFn ) {
                    switch ( this.state ) {
                        case 'fulfilled':
                            successFn( this.value )        // 如果调用了resolve,状态就成了fulfilled,就会执行successFn
                            break
                        case 'rejected':
                            errorFn( this.value )
                            break
                        case 'pendding':
                            this.successFnArray.push( successFn )   // 如果还没调用resolve,状态就是pendding,就先把这些异步函数缓存起来。将来resole时调用
                            this.errorFnArray.push( errorFn )
                    }
                }
            }
    
            var p1 = new Promise2( ( resolve, reject ) => {
                setTimeout( () => {
                    resolve( 'hello' )
                }, 1000 )
    
            } )
    
            p1.then( res => {
                console.log( res + 'world' )
                return res + 'world'
            } )
    ログイン後にコピー
    # を呼び出します。 # # 将来的には then チェーン呼び出しを実装します。

  • then の実装は、JQ の各メソッド呼び出しの後にこれを返します。
  • And Promise 仕様の要件。 、毎回新しい Promise オブジェクトが返される必要があります。

  • したがって、then メソッドを変更するだけで済みます。

この部分は混乱するかもしれませんが、ここで何が行われるかを最初に説明したいと思います。実際には、大きな変化はありません。

保留状態にある場合は、最初にキャッシュされます。今後解決が呼び出されるまで待ちます。

まず、連鎖にはどのような変更が加えられるのでしょうか?戻り値が存在しない場合は、戻り値が返されます。実際には、ロジックは変更されていません。たとえば、ステータスが満たされた場合、successFn

# は直接呼び出されず、

## 代わりに _successFn が呼び出され、この関数は本質的には引き続き successFn() を呼び出します。同時に、呼び出しの戻り値がresolveのパラメータとして使用され、resolve()が呼び出されます。

なぜなら、successFnが呼び出され戻り値が得られた場合、関数が実行されたことを意味します。
  • 次の非同期関数もパラメータとして successFn(res) の戻り値を使用するように、次の非同期関数を実行する必要があります。

以上がPromise の実装アイデアの詳細な分析 (コード例)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:segmentfault.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート