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

来源:互联网 发布:linux好用吗 编辑:程序博客网 时间:2024/06/04 19:10

本文通过一个例子讲述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);}}


原创粉丝点击