2017-08-23 9 views
1

Observable.createと通常のjavascript関数の両方が私と同じように見えます。では、両者の実際の違いは何ですか?Observableと関数の違いは何ですか

var observable= Rx.Observable.create(function (observer) { 
    observer.next("Hello World"); 
}); 
observable.subscribe(function (x) { 
    console.log(x); 
}); 

正常な機能

function myfunction() { 
    console.log('Hello World'); 

} 

myfunction(); 
+1

Observableが重要な理由についてのヒントは次のとおりです。非同期関数からどのように値を返すのですか?別のコードが関数を呼び出すときに通知を受けたい場合はどうすればよいですか? 'setInterval'で呼び出された関数を持っていて、その結果を別の間隔で実行される別の関数とどういう組み合わせにしたいのでしょうか?それは人為的に聞こえるかもしれませんが、そのようなことはいつもgamedevで起こります。 –

答えて

2

私の理解によれば、Observable.createと通常のjavascript関数はどちらも私に似ています。では、両者の実際の違いは何ですか?

これらは両方とも単なる機能です。 Observablesは暗い魔法のように見えるかもしれませんが、Javascriptのオブジェクトや機能には影響します。

基本的には、最初にが必要です。今、だから我々はそれの関数への参照渡し、観察可能なを作成するために

Observable.create(
    function(observer) 
) : Observable {} 

Observable.createの署名を検討

{ 
    //a function to be executed when we want the Observable to emit. Takes 1 arg 
    next:  (val) : void 

    //a func to be executed when an uncaught exception occurs. Takes 1 arg 
    error: (err) : void 

    //a func to be executed when we want the Observable to stop. Takes no arg 
    complete:() : void 
} 

:これは3つのプロパティを持つだけのオブジェクトです。この関数はすぐには実行されませんが、Observableの.subscribe()を呼び出してcreate()が返されたときに実行されます。

意味を分かりやすくするために、変更するたびにテキスト入力の新しい値を放出するオブザーバブルを作成するとします。

let obs = Observable.create(observer=>{ 
    let input = document.querySelector('#myInput'); 
    input.onchange = (event) => { 
    let newVal = event.target.value; 
    if(newVal == 'stop') observer.complete(); 
    else observer.next(event.target.value); 
    } 
}); 

私たちは、この時点で持っているすべては、私たちがサブスクライブを呼び出すときに実行される関数を記憶しているオブジェクトobsです。このファンクションはインタフェースを考慮したパラメータを必要とするため、subscribeは3つのパラメータを取ることが理にかなっています。我々は値の変更をリスニングを開始する準備ができたら:

obs.subscribe(
    // this is the function that will be called from within the Observable 
    // when the value changes. Behind the scenes this function is just 
    // assigned to observer.next 
    newVal => {console.log(newVal)}, 

    error => {}, // assigned to observer.error 

() => {}  // assigned to observer.complete. Executed if new val is 'stop' 
) 

を今、あなたはonchangeイベントが入力で発生するたびに、observer.next(newVal).subscribe()の第一引数の別名である、と呼ばれているか、見!

私の意見では、Observableを素晴らしいものにするのは、どうやって連鎖したり構成したりできるかということです。たぶん、私はすべての価値の変化について学ぶことに興味がありませんが、長さが3以上のものだけに興味があります。何を渡されたが関数であることを

obs.filter(newVal => newVal.length > 3).subscribe('...') 

は予告:代わりに元obsに加入するのは、私は.filter()演算子を適用します。最終結果は、フィルタを通過する出力のみが.subscribe()に達することになります。それはどうですか?このようなもの:

class Observable { 
    filter: (filterFunc) { 
    // create a new observable. This is now what your code will subscribe to. 
    // the original observable is now upstream, and accessed below 
    return Observable.create(observer => { 
     // subscribe to the original observable so we can see input value changes 
     this.subscribe(
     // pass on the value only if it makes it through the filter 
     newVal => {if(filterFunc(newVal)) observer.next(newVal)}, 
     // errors flow downstream 
     error => observer.error(error), 
     // Stop immediately if the upstream observable completes 
     complete => observer.complete() 
    ); 
    }) 
    } 
} 

もう一度、魔法はありません。 .filter()演算子は、元の観測値にサブスクライブした新しい観測値を作成しました。オリジナルが放出されると、newはその値を受け取り、その結果をオブザーバに渡す前にその値を操作します。したがって、obs.filter(filterFunc).subscribe()を実行すると、2番目のオブザーバの出力が表示されます。 Observablesを非常に強力にする数字とflexibility of these operatorsと通知したときのデザインパラダイム。

RxJS 5のアーキテクトがthis videoをお勧めします。同じアーキテクトでわずか数分の場合は、look at this postです。

+0

あなたの説明は私のためにはっきりしています..おかげで..もう1つの質問は、デフォルトでは非同期ですか? – JEMI

+0

@ JEMI no。 Observableに求められている作業に依存します。たとえば、 'Observable.of(5)'は同期です(購読するとすぐに結果が得られます)が、Observable.interval(5000)は5秒間何も出力しません。 Observablesは非同期コードを書くのをより簡単にします。なぜなら、 'subscribe'の内部では、作業が完了したことを確かめることができるからです。 – BeetleJuice

2

それについて考えるための最も簡単な方法は、関数が開始と終了を持っていることです。あなたはそれを呼んで、何かをして終わります。明らかに例外がありますが、この会話の目的のために説明はうまくいくはずです。

一方、観測可能なのは、データのストリームを表示するための「ウィンドウ」と、新しいデータがウィンドウで「見える」ときの対応方法の説明です。関数と観測値の別の違いは、関数が静的データを処理しているのに対し、Observableはストリームを扱っていることです。したがって、多くの混乱が生じている観察可能な部分に時間成分があります。関数は、通常、データのスナップショットを取り、それを操作します。観察者は、時間の経過とともにデータを見て、それに反応する方法を説明します。

Observablesが今日のプログラミングでいかに強力であるかを説明するために、以下の例を考えてみましょう。 「関数アプローチ」のオブジェクト(静的データ)がUsersで、観測可能なデータストリーム(時間の流れ)がUsersDataであり、両方ともアプリケーション内のユーザーのデータを保持しているとします。アプリケーションに登録されているすべてのユーザーを表示する必要があります。

FUNCTIONアプローチ

function getUsers() { 
    return Users; 
} 

getUsers(); 

それが呼ばれていたときに、このアプローチは、すべてのユーザーが返されます。ページが読み込まれ、モデルがインスタンス化されると考えられます。ページが読み込まれたら、静的データに変換します。

観測可能APPROACH

function getUsers() { 
    UserDataObservable.subscribe(_Users => { 
     this.Users = _Users 
    } 
} 

getUsers(); 

私たちは順番に順番にビューを更新し、モデルのUsersプロパティを更新する観測可能に新しいデータをプッシュすることができ、観察UserDataに観測可能なアプローチsubscribes。つまり、最初にデータのスナップショットを取得するだけでなく、データにウィンドウを開き、新しいデータを観察して反応させることができます。

元の質問に戻るには、一度呼び出すと関数が実行されますが、観測可能な状態に文字列を押し続けると、コンソールにログが記録され続けます。

0

離散または連続で動作するオブジェクト/エンティティが観測可能です。離散した情報セットの例は、配列内の要素であり、継続的な情報のためにはあらゆるイベントを考慮することができます。そして、購読者は、毎回オブザーバーによって暗黙のうちに呼び出され/与えられる情報を必要とするある人/機能者です。

例としてYouTube bellを使用してください。 YouTubeは、登録したベルアイコンのチャンネル の更新を通知します。あなたがそのアップデートに興味があるかどうかに関係なく、

しかし、関数は明示的に機能しますが、関数を呼び出すときにのみ機能します。

YouTubeのチャンネルにアクセスしてビデオを観るのが好きです。あなたの興味に基づいて、いくつかのビデオを見ることができますが、すべてを見ることはできません。

0

私も

観測は時間、関数ができないものの上に複数の値を「返す」ことができます彼らの公式ドキュメントからいくつかの良い説明を得ました。これを行うことはできません:

function foo() { 
    console.log('Hello'); 
    return 42; 
    return 100; // dead code. will never happen 
} 

関数は1つの値しか返しません。観測、しかし、これを行うことができます。

var foo = Rx.Observable.create(function (observer) { 
    console.log('Hello'); 
    observer.next(42); 
    observer.next(100); // "return" another value 
    observer.next(200); // "return" yet another 
}); 

console.log('before'); 
foo.subscribe(function (x) { 
    console.log(x); 
}); 
console.log('after'); 

結論:

  • func.callは() "が同期私に一つの値を与える"
  • observable.subscribe()手段」を意味私に値の任意の量を与える、 同期または非同期 "
関連する問題