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

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


你可能感兴趣的:(一个Javacript callback注册与调用的例子)