您的位置:首页 > 编程语言 > Java开发

一个Javacript callback注册与调用的例子

2011-08-24 15:42 302 查看
本文通过一个例子讲述javascript如何注册一个函数到中间件,中间件如何调用这个函数,传递相关的参数。

先创建头文件JSBaseTv.h声明一个c++的类,包含两个函数和一个变量:

#include <JavaScriptCore/JavaScript.h>

using namespace std;

namespace Sample
{
class JSBaseTv
{
public:
static JSValeRef registerScanCallback(JSContextRef ctx, JSObjectRef function,JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[],JSValueRef *exception);
static JSValueRef triggerScanCallback(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception);

private:
statice JSObjectRef channelScanCallback;
}
}


再创建JSBaseTv.cpp, registerScanCallback用以javascript来注册callback函数。channelScanCallback保存回调函数,triggerScanCallback用以触发回调函数。

#include <JavaScriptCore/JavaScript.h>
#include "JSBaseTv.h"
using namespace std;

namespace Sample
{
JSObjectRef JSBaseTv::channelScanCallback;

JSValeRef registerScanCallback(JSContextRef ctx, JSObjectRef function,JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[],JSValueRef *exception)
{
if(argumentCount < 1)
{
*exception = JSValueMakeString(ctx, JSStringCreateWithUTF8CString("scan callback argument invalid."));
return JSValueMakeNull(ctx);
}

JSObjectRef cb = const_cast<JSObjectRef>(arguments[0]);
if(!JSObjectIsFunction(ctx,cb))
{
channelScanCallback = NULL;
return JSValueMakeNull(ctx);
}

channelScanCallback = cb;
return JSValueMakeNull(ctx);

}

JSValueRef triggerScanCallback(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception)
{
if(channelScanCallback == NULL)
{
*exception = JSValueMakeString(ctx, JSStringCreateWithUTF8CString("callback is null."));
return JSValueMakeNull(ctx);
}
//just for testing.
JSValueRef args[3];
args[0] = JSValueMakeNumber(ctx,15);
args[1] = JSValueMakeNumber(ctx,7);
args[2] = JSValueMakeNumber(ctx,18);
JSObjectCallAsFunction(ctx,channelScanCallback,NULL,3,args,NULL);
return JSValueMakeNull(ctx);

}
}


triggerScanCallback返回了三个参数。

再建立一个javascript 文件JSBaseTv.js

var sample =
{
register:function()
{
....
//register callback;
$BaseTv.registerScanCallback(sample.handleCallback);

....

}

handleCallback:function(tvNum, radioNum, progress)
{

alert("tvNum " + tvNum);
alert("radioNum " + radioNum);
alert("progress " + progress);

}
}


register函数把handleCallback注册下去。当triggerScanCallback调用时,handleCallback被调用,在这个例子中它会得到15,7,18这三个值。

我们也可以将参数封装在一个结构里面。如下:

JSValueRef triggerScanCallback(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception)
{
if(channelScanCallback == NULL)
{
*exception = JSValueMakeString(ctx, JSStringCreateWithUTF8CString("callback is null."));
return JSValueMakeNull(ctx);
}

//just for testing.
JSValueRef args[1];

/* create an object */
JSObjectRef para = JSObjectMake(ctx,NULL,NULL);

//create four properties: type, arg0, arg1, arg2
JSStringRef eventType = JSStringCreateWithUTF8CString("type");
JSStringRef name = JSStringCreateWithUTF8CString("eventChannelScanProgress");
JSValueRef  eventName = JSValueMakeString(ctx,name);

JSStringRef argName0 = JSStringCreateWithUTF8CString("arg0");
JSValueRef  argVal0  = JSValueMakeNumber(ctx,20);
JSStringRef argName1 = JSStringCreateWithUTF8CString("arg1");
JSValueRef  argVal1  = JSValueMakeNumber(ctx,21);
JSStringRef argName2 = JSStringCreateWithUTF8CString("arg2");
JSValueRef  argVal2  = JSValueMakeNumber(ctx,50);

/* set the value for each property */
JSObjectSetProperty(ctx,para,eventType,eventName,kJSPropertyAttributeNone,0);
JSObjectSetProperty(ctx,para,argName0,argVal0,kJSPropertyAttributeNone,0);
JSObjectSetProperty(ctx,para,argName1,argVal1,kJSPropertyAttributeNone,0);
JSObjectSetProperty(ctx,para,argName2,argVal2,kJSPropertyAttributeNone,0);

args[0] = para;

JSObjectCallAsFunction(ctx,channelScanCallback,NULL,1,args,NULL);

return JSValueMakeNull(ctx);

}
}


修改JAVASCRIPT

var sample =
{
register:function()
{
....
//register callback;
$BaseTv.registerScanCallback(sample.handleCallback);

....

}

handleCallback:function(evt)
{
alert("event type:" + evt.type);
alert("tvNum " + evt.arg0);
alert("radioNum " + evt.arg1);
alert("progress " + evt.arg2);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: