>  기사  >  웹 프론트엔드  >  JS 메시지 메커니즘과 이벤트 메커니즘_javascript 기술에 대한 이해에 대해 이야기해보겠습니다.

JS 메시지 메커니즘과 이벤트 메커니즘_javascript 기술에 대한 이해에 대해 이야기해보겠습니다.

WBOY
WBOY원래의
2016-05-16 15:05:381503검색

메시지/이벤트 메커니즘은 거의 모든 개발 언어에서 발견되는 메커니즘입니다. 이는 deviceone에만 국한되지 않으며 일부 언어에서는 메시지(Message)라고도 합니다. , 원칙은 비슷합니다. 일부 구현 방법이 조금 더 복잡하다는 것뿐입니다. 우리의 DeviceOne 통합 이름은 메시지라고 합니다.

메시지 기본 개념

이 메커니즘에 익숙하지 않은 초보자도 있습니다. 몇 가지 기본 개념을 간략하게 소개하겠습니다. 익숙하다면 이 부분을 건너뛰어도 됩니다.
메시지는 다음과 같은 기본 부분을 포함하는 데이터 구조로 이해될 수 있습니다.

1. 메시지 소스: 메시지의 소스이자 메시지를 보내는 객체입니다

2. 메시지 이름: 메시지의 고유 식별자입니다.

3. 메시지 데이터: 메시지 전송 후 첨부된 데이터, 데이터가 비어 있을 수 있음

메시지는 두 가지 유형으로 나눌 수 있습니다:

1. 시스템 메시지: 운영체제나 디바이스원 시스템에서 보내는 메시지입니다. 메시지 이름은 고정되어 있습니다.

2. 맞춤 메시지: 메시지는 개발자가 직접 정의하여 전송합니다. 메시지 이름은 임의이며 임의로 정의할 수 있습니다.

예:

예를 들어 사용자가 do_Button 버튼을 클릭하면 다음 세 부분이 포함된 시스템 메시지가 트리거됩니다.

1. 메시지 출처: 사용자 클릭의 버튼 개체

2. 메시지 이름: 터치

3. 메시지 데이터: 이 메시지에는 데이터가 포함되어 있지 않습니다

예를 들어, 사용자는 세 부분으로 구성된 do_Button 버튼을 통해 맞춤 이벤트를 트리거합니다.

1.메시지 소스: 버튼 객체

2. 메시지 이름: 사용자가 원하는 대로 정의할 수 있으며 aaa, bbb, ccc로 지정할 수 있습니다.

3. 메시지 데이터: 메시지가 실행될 때 첨부된 데이터가 설정됩니다

게시/구독 모드

Publish/Subscribe 패턴은 가장 일반적으로 사용되는 디자인 패턴 중 하나이며 메시징 메커니즘의 핵심입니다. 두 개의 독립된 객체가 서로 의존하지 않도록 결합을 줄이는 것이 특징입니다. 간단한 소개이므로 친숙한 학생들은 건너뛸 수 있습니다.

먼저 현실의 간단한 예를 들어 이 문제를 설명하겠습니다. 아래 그림을 참조하세요.


이 사진을 보면 알 수 있습니다

1. 소비자와 출판사는 서로 알지 못합니다. 소비자는 자신이 원하는 잡지가 어느 출판사에서 발행되는지 알 필요가 없습니다. 출판사는 자신이 출판하려는 잡지를 구체적으로 주문한 사람이 누구인지 알 필요가 없습니다.

2. 소비자와 출판사 모두 우체국을 알아야 합니다.

3. 소비자는 소비자의 이름과 주소, 구독하려는 잡지 이름을 우체국에 알려야 합니다

4. 여러 소비자가 동일한 잡지를 구독할 수 있습니다

5. 우체국은 잡지를 수령한 후 소비자에게 하나씩 알리고 동시에 소비자에게 잡지를 전달합니다.

위의 실제 사례를 읽은 후, 이해를 돕기 위해 추상적인 설명을 살펴보겠습니다.

은 위의 실제 예시 설명에 해당합니다.

1. 시스템/개발자와 함수 개체는 서로 의존하지 않습니다. 시스템/개발자는 메시지를 트리거할 뿐이며 메시지를 받는 사람은 상관하지 않습니다.

2. 시스템/개발자 및 함수 개체는 메시지 소스 개체를 얻을 수 있어야 합니다

3. 함수 개체가 메시지를 구독할 때 메시지 이름과 함수 개체에 대한 참조를 표시해야 합니다.

4. 여러 함수 개체가 동일한 메시지 소스와 동일한 이름을 가진 메시지를 구독할 수 있습니다

5. 메시지 소스가 메시지를 트리거하면 모든 구독자에게 하나씩 알리고 콜백 함수 개체에 데이터를 전달합니다.

추상적인 설명을 읽은 후, 마지막으로 do_Button을 예로 들어 deviceone 개발의 실제 예를 살펴보겠습니다.

1. 사용자가 버튼을 클릭하고 터치하면 시스템은 버튼 개체를 메시지 소스로 가져오고 "터치" 메시지를 구독하는 모든 함수 개체를 실행합니다. 이 메시지를 받으면 함수가 실행됩니다.

//获取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. 버튼 객체에 대해 두 개의 사용자 정의 메시지 "message1"과 "message2"를 정의하고 두 개의 함수 객체가 이 두 메시지를 각각 구독하도록 할 수 있습니다. 하지만 결국 개발자는 fire 함수를 호출하여 이 메시지를 트리거해야 합니다. 이것이 시스템 메시지와 다릅니다.

//获取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一次后就取消订阅了。

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.