欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

談一談JS消息機(jī)制和事件機(jī)制的理解

 更新時(shí)間:2016年04月14日 10:51:30   作者:AndButcher  
消息/事件機(jī)制是幾乎所有開(kāi)發(fā)語(yǔ)言都有的機(jī)制,并不是deviceone的獨(dú)創(chuàng),在某些語(yǔ)言稱(chēng)之為消息(Event),有些地方稱(chēng)之為(Message).接下來(lái)通過(guò)本文給大家介紹JS事件和消息機(jī)制的理解 ,需要的朋友一起學(xué)習(xí)吧

消息/事件機(jī)制是幾乎所有開(kāi)發(fā)語(yǔ)言都有的機(jī)制,并不是deviceone的獨(dú)創(chuàng),在某些語(yǔ)言稱(chēng)之為消息(Event),有些地方稱(chēng)之為(Message). 其實(shí)原理是類(lèi)似的,只不過(guò)有些實(shí)現(xiàn)的方式要復(fù)雜一點(diǎn)。我們deviceone統(tǒng)一就叫消息.

消息基礎(chǔ)概念

還有一些初學(xué)者不太熟悉這個(gè)機(jī)制,我們先簡(jiǎn)單介紹一些基礎(chǔ)概念,如果熟悉的人可以跳過(guò)這個(gè)部分。
一個(gè)/條消息可以理解為是一個(gè)數(shù)據(jù)結(jié)構(gòu),包含以下幾個(gè)基本部分:

1.消息源:就是消息的來(lái)源,發(fā)出這個(gè)消息的對(duì)象

2.消息名:就是消息的唯一標(biāo)示

3.消息數(shù)據(jù):消息發(fā)出后附帶的數(shù)據(jù),有可能數(shù)據(jù)是空

消息從種類(lèi)上又可以分為2種:

1.系統(tǒng)消息:由操作系統(tǒng)或deviceone系統(tǒng)發(fā)送出來(lái)的消息,消息的名稱(chēng)是固定的。

2.自定義消息:由開(kāi)發(fā)者自己定義,自己發(fā)送出來(lái)的消息,消息的名字是隨意的,可以任意定義。

舉例說(shuō)明:

比如用戶(hù)點(diǎn)擊一個(gè)do_Button按鈕,就會(huì)觸發(fā)一個(gè)系統(tǒng)消息,包含3個(gè)部分:

1.消息源:用戶(hù)點(diǎn)中的button對(duì)象

2.消息名:touch

3.消息數(shù)據(jù):這個(gè)消息沒(méi)有附帶數(shù)據(jù)

比如用戶(hù)通過(guò)do_Button按鈕觸發(fā)一個(gè)自定義事件,包含3個(gè)部分:

1.消息源: button對(duì)象

2.消息名:用戶(hù)隨便定義,叫aaa,bbb,ccc都可以

3.消息數(shù)據(jù):附帶的數(shù)據(jù)由觸發(fā)消息的時(shí)候設(shè)定

發(fā)布/訂閱模式

發(fā)布/訂閱模式是最常用的設(shè)計(jì)模式之一,是消息機(jī)制的核心,其特點(diǎn)就是降低耦合度,讓二個(gè)獨(dú)立的對(duì)象不互相依賴(lài)。簡(jiǎn)單介紹一下,熟悉的同學(xué)可以跳過(guò)。

我們先從現(xiàn)實(shí)的一個(gè)簡(jiǎn)單例子來(lái)說(shuō)明這個(gè)問(wèn)題,參考下圖:


從這個(gè)圖我們可以看出

1.消費(fèi)者和出版社互相不認(rèn)識(shí),消費(fèi)者不需要了解他想要的雜志是具體哪家出版社出的;出版社也不需要了解具體是哪個(gè)人定了他們出版社發(fā)行的書(shū)。

2.消費(fèi)者和出版社必須都認(rèn)識(shí)郵局。

3.消費(fèi)者需要告訴郵局消費(fèi)者的名字地址以及想要訂閱的雜志名字

4.可以多個(gè)消費(fèi)者訂閱同一本雜志

5.郵局拿到雜志后,會(huì)一一通知消費(fèi)者,通知的時(shí)候同時(shí)把雜志送到消費(fèi)者手里。

看完上面現(xiàn)實(shí)例子,我們?cè)賮?lái)看抽象的描述會(huì)更清晰一點(diǎn),看下圖:

和上面的實(shí)際例子描述一一對(duì)應(yīng):

1.系統(tǒng)/開(kāi)發(fā)者和函數(shù)對(duì)象互相不依賴(lài),系統(tǒng)/開(kāi)發(fā)者只管觸發(fā)一個(gè)消息,并不關(guān)心誰(shuí)去接受

2.系統(tǒng)/開(kāi)發(fā)者和函數(shù)對(duì)象必須能獲取到消息源對(duì)象

3.函數(shù)對(duì)象訂閱消息的時(shí)候需要標(biāo)示消息的名稱(chēng)和函數(shù)對(duì)象的引用

4.可以多個(gè)函數(shù)對(duì)象訂閱同一個(gè)消息源同一名字的消息

5.消息源觸發(fā)消息會(huì)一一通知所有訂閱者,并把data數(shù)據(jù)傳遞到回調(diào)函數(shù)對(duì)象

看完抽象的描述,我們最后來(lái)看實(shí)際的deviceone開(kāi)發(fā)的例子,還是以do_Button為例子。

1. 當(dāng)用戶(hù)點(diǎn)擊一個(gè)button,觸摸到的時(shí)候,系統(tǒng)會(huì)獲取到button這個(gè)對(duì)象作為消息源,fire一個(gè)”touch”消息,任何訂閱了”touch”消息的函數(shù)對(duì)象都會(huì)接收到這個(gè)消息并引起函數(shù)的執(zhí)行。

//獲取button對(duì)象
var btn_hello = ui("btn_hello");
//定義函數(shù)對(duì)象
function f(){
//當(dāng)btn_hello這個(gè)按鈕接收到手指點(diǎn)擊就會(huì)執(zhí)行下面的代碼
deviceone.print("f 函數(shù)接收到點(diǎn)擊觸發(fā)消息")
}
function f(){
//當(dāng)btn_hello這個(gè)按鈕接收到手指點(diǎn)擊就會(huì)執(zhí)行下面的代碼
deviceone.print("f 函數(shù)接收到點(diǎn)擊觸發(fā)消息")
}
//f,f訂閱button的touch消息
btn_hello.on("touch",f);
btn_hello.on("touch",f);

2. 我們可以為button對(duì)象定義2個(gè)自定義的消息”message1”和”message2”,分別有2個(gè)函數(shù)對(duì)象訂閱這2個(gè)消息。但是最后要觸發(fā)這個(gè)消息必須是開(kāi)發(fā)者通過(guò)調(diào)用fire函數(shù)才能觸發(fā),這就是和系統(tǒng)消息的區(qū)別。

//獲取button對(duì)象
var btn_hello = ui("btn_hello");
//定義函數(shù)對(duì)象
function f(d){
//當(dāng)btn_hello這個(gè)按鈕接收到開(kāi)發(fā)者觸發(fā)的消息message就會(huì)執(zhí)行下面的代碼
deviceone.print("f 函數(shù)接收到message消息,消息的數(shù)據(jù)是:"+d)
}
function f(d){
//當(dāng)btn_hello這個(gè)按鈕接收到開(kāi)發(fā)者觸發(fā)的消息message就會(huì)執(zhí)行下面的代碼
deviceone.print("f 函數(shù)接收到message消息,消息的數(shù)據(jù)是:"+d)
}
//f,f訂閱button的touch消息
btn_hello.on("message",f);
btn_hello.on("message",f);
//觸發(fā)消息
btn_hello.fire("message","data");
btn_hello.fire("message","data");

看到這里,你肯定會(huì)奇怪,為什么我們要在button上自定義對(duì)象?這有神馬意義?其實(shí)確實(shí)沒(méi)有意義也沒(méi)有必要,這里只是拿button舉例子,在常規(guī)的開(kāi)發(fā)中,基本不會(huì)這么用。

消息的使用

前面講了這么多,現(xiàn)在才是deviceone消息的使用。使用其實(shí)很簡(jiǎn)單,上面的例子基本說(shuō)明的了系統(tǒng)事件和自定義事件的使用方法。

有幾個(gè)概念再說(shuō)明一下

1.deviceone的所有對(duì)象,包括UI,MM,SM對(duì)象都可以是消息源

// SM對(duì)象可以是消息源
var page = sm("do_Page");
page.on("loaded",function()){
// 這個(gè)是page對(duì)象的系統(tǒng)消息,這個(gè)消息不需要手動(dòng)觸發(fā),系統(tǒng)會(huì)自動(dòng)觸發(fā)
}
page.on("message",function(d)){
// 這個(gè)是page對(duì)象的自定義消息
}
page.fire("message","data");
// MM對(duì)象可以是消息源
var http = mm("do_Http");
http.on("result",function()){
// 這個(gè)是http對(duì)象的系統(tǒng)消息,這個(gè)消息不需要手動(dòng)觸發(fā),接受到http服務(wù)端的反饋后會(huì)自動(dòng)觸發(fā)
}
http.on("message",function(d)){
// 這個(gè)是http對(duì)象的自定義消息
}
http.fire("message","data");
//UI對(duì)象可以是消息源
var alayout = ui("alayout_id");
alayout.on("touch",function()){
// 這個(gè)是alayout對(duì)象的系統(tǒng)消息,這個(gè)消息不需要手動(dòng)觸發(fā),手機(jī)點(diǎn)擊就會(huì)觸發(fā)
}
alayout.on("message",function(d)){
// 這個(gè)是alayout對(duì)象的自定義消息
}
alayout.fire("message","data");

2.消息源對(duì)象有作用域,所以訂閱和觸發(fā)的消息源必須是是一個(gè)作用域的同一個(gè)對(duì)象。這里結(jié)合數(shù)據(jù)分享和數(shù)據(jù)傳遞文檔來(lái)理解。

看以下的例子,test1.ui和test2.ui有可能在一個(gè)page作用域,也有可能不在一個(gè)作業(yè)域,只有在一個(gè)作用域fire的消息才能正確送達(dá)回調(diào)函數(shù)。

判斷是否一樣,可以通過(guò)打印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觸發(fā)消息
var page = sm("do_Page");
deviceone.print(page.getAddress());
page.fire("message","data");

如果不在同一page作用域,則可以把消息訂閱在2個(gè)page都能共享到的app作用域
上面的代碼改成:

//在test.ui.js里訂閱消息
var app = sm("do_App");
app.on("message",function(d)){
deviceone.print(d);
}
//在test.ui.js觸發(fā)消息
var app = sm("do_App");
app.fire("message","data");

3.同樣的函數(shù)對(duì)象可以重復(fù)訂閱一個(gè)對(duì)象源的消息,觸發(fā)消息的時(shí)候會(huì)使函數(shù)執(zhí)行多次,這是初學(xué)者經(jīng)常犯的錯(cuò)誤。

var page = sm("do_Page");
var count = ;
function f(){
deviceone.print("執(zhí)行次數(shù)"+(count++));
}
page.on("message",f);
page.on("message",f);
page.fire("message");

看上面的例子,如果執(zhí)行的話,會(huì)打印2此,因?yàn)橛嗛喠?次,或許你會(huì)說(shuō)誰(shuí)會(huì)寫(xiě)這樣的代碼?實(shí)際情況肯定沒(méi)有這么容易看出來(lái)執(zhí)行了重復(fù)的on函數(shù),實(shí)際情況經(jīng)常是比如在點(diǎn)擊事件里執(zhí)行on函數(shù),每點(diǎn)擊一下按鈕,就重復(fù)訂閱一次。

4.消息的訂閱一定要在消息的觸發(fā)之前,這是初學(xué)者經(jīng)常犯的錯(cuò)誤。

var page = sm("do_Page");
var count = ;
function f(){
deviceone.print("執(zhí)行次數(shù)"+(count++));
}
page.fire("message");
page.on("message",f);

看上面的例子,如果執(zhí)行的話,會(huì)沒(méi)有效果,或許你會(huì)說(shuō)誰(shuí)會(huì)寫(xiě)這樣的代碼?實(shí)際情況肯定沒(méi)有這么容易看出來(lái)順序反了,實(shí)際情況經(jīng)常是比如on函數(shù)執(zhí)行在某一個(gè)函數(shù)的回調(diào)函數(shù)里,你無(wú)法確定回調(diào)函數(shù)啥時(shí)候執(zhí)行,是否是在fire之前執(zhí)行。一般碰到這種情況可以加幾個(gè)deviceone.print打印一下看看是on先執(zhí)行還是fire先執(zhí)行。

5.有訂閱就有取消訂閱,取消訂閱是off函數(shù),之所以很少用,是因?yàn)閏losePage的時(shí)候會(huì)自動(dòng)把當(dāng)前page作用域訂閱的消息全部釋放。

但是如果消息訂閱在app作用域,就要注意,可能需要手動(dòng)去取消訂閱。否則就會(huì)出現(xiàn)觸發(fā)消息的時(shí)候會(huì)使函數(shù)執(zhí)行多次的問(wèn)題。

var page = sm("do_Page");
var count = ;
function f(){
deviceone.print("執(zhí)行次數(shù)"+(count++));
}
page.on("message",f);
page.fire("message");
.page.off("message");
page.fire("message");

看上面的例子,打印只會(huì)執(zhí)行一次,因?yàn)閒ire一次后就取消訂閱了。

相關(guān)文章

最新評(píng)論