Heim > Artikel > Web-Frontend > Lassen Sie uns über das Verständnis des JS-Nachrichtenmechanismus und des Ereignismechanismus sprechen. Javascript-Fähigkeiten
Der Nachrichten-/Ereignismechanismus ist ein Mechanismus, der in fast allen Entwicklungssprachen zu finden ist. In einigen Sprachen wird er tatsächlich als Nachricht (Ereignis) bezeichnet Das Prinzip ist ähnlich, nur sind einige Implementierungsmethoden etwas komplizierter. Der einheitliche Name unseres Geräts heißt Nachricht.
Grundlegende Konzepte von Nachrichten
Es gibt einige Anfänger, die mit diesem Mechanismus nicht vertraut sind. Lassen Sie uns kurz einige grundlegende Konzepte vorstellen. Wenn Sie damit vertraut sind, können Sie diesen Teil überspringen.
Eine Nachricht kann als Datenstruktur verstanden werden, die die folgenden Grundteile umfasst:
1. Nachrichtenquelle: Dies ist die Quelle der Nachricht und das Objekt, das die Nachricht sendet
2. Nachrichtenname: Dies ist die eindeutige Kennung der Nachricht
3. Nachrichtendaten: Die nach dem Senden der Nachricht angehängten Daten können leer sein
Nachrichten können in zwei Typen unterteilt werden:
1. Systemnachricht: Eine vom Betriebssystem oder Gerät gesendete Nachricht. Der Name der Nachricht ist festgelegt.
2. Benutzerdefinierte Nachricht: Die Nachricht wird vom Entwickler selbst definiert und von ihm selbst gesendet. Der Name der Nachricht ist beliebig und kann beliebig definiert werden.
Beispiel:
Wenn der Benutzer beispielsweise auf die Schaltfläche „do_Button“ klickt, wird eine Systemmeldung ausgelöst, die aus drei Teilen besteht:
1. Nachrichtenquelle: Schaltflächenobjekt im Benutzerklick
2. Nachrichtenname: berühren
3. Nachrichtendaten: Diese Nachricht enthält keine Daten
Zum Beispiel löst der Benutzer ein benutzerdefiniertes Ereignis über die Schaltfläche „do_Button“ aus, die aus drei Teilen besteht:
1.Nachrichtenquelle: Schaltflächenobjekt
2. Nachrichtenname: Der Benutzer kann ihn nach Wunsch definieren, er kann aaa, bbb, ccc heißen
3. Nachrichtendaten: Die angehängten Daten werden festgelegt, wenn die Nachricht ausgelöst wird
Publish/Subscribe-Modus
Das Publish/Subscribe-Muster ist eines der am häufigsten verwendeten Entwurfsmuster und stellt den Kern des Nachrichtenmechanismus dar. Seine Eigenschaft besteht darin, die Kopplung zu reduzieren, sodass zwei unabhängige Objekte nicht voneinander abhängig sind. Eine kurze Einführung, vertraute Schüler können sie überspringen.
Lassen Sie uns dieses Problem zunächst anhand eines einfachen Beispiels aus der Realität veranschaulichen, siehe Bild unten:
Das können wir auf diesem Bild sehen
1. Verbraucher und Verlage müssen nicht wissen, bei welchem Verlag das von ihnen gewünschte Magazin veröffentlicht wird.
2. Sowohl Verbraucher als auch Verleger müssen die Post kennen.
3. Verbraucher müssen der Post den Namen und die Adresse des Verbrauchers sowie den Namen der Zeitschrift mitteilen, die sie abonnieren möchten
4. Mehrere Verbraucher können dasselbe Magazin abonnieren
5. Nachdem die Post die Zeitschrift erhalten hat, benachrichtigt sie die Verbraucher einzeln und liefert die Zeitschrift gleichzeitig an die Verbraucher aus.
Nachdem wir die obigen Beispiele aus der Praxis gelesen haben, schauen wir uns zur Verdeutlichung die abstrakte Beschreibung an: Schauen Sie sich das Bild unten an:
entspricht der tatsächlichen Beispielbeschreibung oben:
1. Das System/der Entwickler und das Funktionsobjekt sind nicht voneinander abhängig. Das System/der Entwickler löst nur eine Nachricht aus und es ist ihm egal, wer sie empfängt.
2. Die System-/Entwickler- und Funktionsobjekte müssen in der Lage sein, das Nachrichtenquellenobjekt abzurufen
3. Wenn ein Funktionsobjekt eine Nachricht abonniert, muss es den Namen der Nachricht und den Verweis auf das Funktionsobjekt angeben
4. Mehrere Funktionsobjekte können Nachrichten mit derselben Nachrichtenquelle und demselben Namen abonnieren
5. Wenn die Nachrichtenquelle eine Nachricht auslöst, benachrichtigt sie alle Abonnenten nacheinander und übergibt die Daten an das Callback-Funktionsobjekt
Nachdem wir die abstrakte Beschreibung gelesen haben, schauen wir uns schließlich das tatsächliche Beispiel der Entwicklung von deviceone an, wobei wir do_Button als Beispiel nehmen.
1. Wenn der Benutzer auf eine Schaltfläche klickt und diese berührt, erhält das System das Schaltflächenobjekt als Nachrichtenquelle und löst jedes Funktionsobjekt aus, das die „Berührungs“-Nachricht abonniert Wenn Sie diese Nachricht erhalten, wird die Funktion ausgeführt.
//获取button对象 var btn_hello = ui("btn_hello"); //定义函数对象 function f(){ //当btn_hello这个按钮接收到手指点击就会执行下面的代码 deviceone.print("f 函数接收到点击触发消息") } function f(){ //当btn_hello这个按钮接收到手指点击就会执行下面的代码 deviceone.print("f 函数接收到点击触发消息") } //f,f订阅button的touch消息 btn_hello.on("touch",f); btn_hello.on("touch",f);
2. Wir können zwei benutzerdefinierte Nachrichten „message1“ und „message2“ für das Schaltflächenobjekt definieren und diese beiden Nachrichten jeweils von zwei Funktionsobjekten abonnieren lassen. Letztendlich muss der Entwickler diese Nachricht jedoch durch den Aufruf der Feuerfunktion auslösen. Dies ist der Unterschied zur Systemnachricht.
//获取button对象 var btn_hello = ui("btn_hello"); //定义函数对象 function f(d){ //当btn_hello这个按钮接收到开发者触发的消息message就会执行下面的代码 deviceone.print("f 函数接收到message消息,消息的数据是:"+d) } function f(d){ //当btn_hello这个按钮接收到开发者触发的消息message就会执行下面的代码 deviceone.print("f 函数接收到message消息,消息的数据是:"+d) } //f,f订阅button的touch消息 btn_hello.on("message",f); btn_hello.on("message",f); //触发消息 btn_hello.fire("message","data"); btn_hello.fire("message","data");
看到这里,你肯定会奇怪,为什么我们要在button上自定义对象?这有神马意义?其实确实没有意义也没有必要,这里只是拿button举例子,在常规的开发中,基本不会这么用。
消息的使用
前面讲了这么多,现在才是deviceone消息的使用。使用其实很简单,上面的例子基本说明的了系统事件和自定义事件的使用方法。
有几个概念再说明一下
1.deviceone的所有对象,包括UI,MM,SM对象都可以是消息源
// SM对象可以是消息源 var page = sm("do_Page"); page.on("loaded",function()){ // 这个是page对象的系统消息,这个消息不需要手动触发,系统会自动触发 } page.on("message",function(d)){ // 这个是page对象的自定义消息 } page.fire("message","data"); // MM对象可以是消息源 var http = mm("do_Http"); http.on("result",function()){ // 这个是http对象的系统消息,这个消息不需要手动触发,接受到http服务端的反馈后会自动触发 } http.on("message",function(d)){ // 这个是http对象的自定义消息 } http.fire("message","data"); //UI对象可以是消息源 var alayout = ui("alayout_id"); alayout.on("touch",function()){ // 这个是alayout对象的系统消息,这个消息不需要手动触发,手机点击就会触发 } alayout.on("message",function(d)){ // 这个是alayout对象的自定义消息 } alayout.fire("message","data");
2.消息源对象有作用域,所以订阅和触发的消息源必须是是一个作用域的同一个对象。这里结合数据分享和数据传递文档来理解。
看以下的例子,test1.ui和test2.ui有可能在一个page作用域,也有可能不在一个作业域,只有在一个作用域fire的消息才能正确送达回调函数。
判断是否一样,可以通过打印page的地址 page.getAddress().
//在test.ui.js里订阅消息 var page = sm("do_Page"); deviceone.print(page.getAddress()); page.on("message",function(d)){ deviceone.print(d); } //在test.ui.js触发消息 var page = sm("do_Page"); deviceone.print(page.getAddress()); page.fire("message","data");
如果不在同一page作用域,则可以把消息订阅在2个page都能共享到的app作用域
上面的代码改成:
//在test.ui.js里订阅消息 var app = sm("do_App"); app.on("message",function(d)){ deviceone.print(d); } //在test.ui.js触发消息 var app = sm("do_App"); app.fire("message","data");
3.同样的函数对象可以重复订阅一个对象源的消息,触发消息的时候会使函数执行多次,这是初学者经常犯的错误。
var page = sm("do_Page"); var count = ; function f(){ deviceone.print("执行次数"+(count++)); } page.on("message",f); page.on("message",f); page.fire("message");
看上面的例子,如果执行的话,会打印2此,因为订阅了2次,或许你会说谁会写这样的代码?实际情况肯定没有这么容易看出来执行了重复的on函数,实际情况经常是比如在点击事件里执行on函数,每点击一下按钮,就重复订阅一次。
4.消息的订阅一定要在消息的触发之前,这是初学者经常犯的错误。
var page = sm("do_Page"); var count = ; function f(){ deviceone.print("执行次数"+(count++)); } page.fire("message"); page.on("message",f);
看上面的例子,如果执行的话,会没有效果,或许你会说谁会写这样的代码?实际情况肯定没有这么容易看出来顺序反了,实际情况经常是比如on函数执行在某一个函数的回调函数里,你无法确定回调函数啥时候执行,是否是在fire之前执行。一般碰到这种情况可以加几个deviceone.print打印一下看看是on先执行还是fire先执行。
5.有订阅就有取消订阅,取消订阅是off函数,之所以很少用,是因为closePage的时候会自动把当前page作用域订阅的消息全部释放。
但是如果消息订阅在app作用域,就要注意,可能需要手动去取消订阅。否则就会出现触发消息的时候会使函数执行多次的问题。
var page = sm("do_Page"); var count = ; function f(){ deviceone.print("执行次数"+(count++)); } page.on("message",f); page.fire("message"); .page.off("message"); page.fire("message");
看上面的例子,打印只会执行一次,因为fire一次后就取消订阅了。