js不论浏览器还是后台,一般函数很少返回值,大多都是回调。如下形态:
// 返回值得形式
var results = rainfall.calculate_results(locations);
results.forEach(function(result){
// .. print the result
});
// 回调的形式
rainfall.calculate_results(locations, function(results){
results.forEach(function(result){
// .. print the result
});
});
回调实现
步骤:
1.参数实例化回调对象(回调函数也是对象);
2.计算结果,构造回调参数;
3.通过Call调用回调函数。
js调用
// 库引用
const callback = require('./build/Release/callback');
// 回调函数
var callme = function(message) {
console.log(message);
}
// 把回调函数当参数往里传
back.callthis_withthis(callme, "This is an important message");
Addon实现
void CallThisWithThis(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
// 1.参数实例化回调对象(回调函数也是对象);
//处理代码 。。。
// 2.计算结果,构造回调参数;
Local<Function> cb = Local<Function>::Cast(args[0]);
Local<Value> argv[1] = {args[1]};
// 3.通过Call调用回调函数。
cb->Call(Null(isolate), 1, argv);
}
void Init(Local<Object> exports, Local<Object> module) {
// 函数注册
NODE_SET_METHOD(exports,"callthis_withthis", CallThisWithThis);
}
同步Sync
js调用
// 打印结果
var print_rain_results = function(results) {
results.forEach(function(result, i){
console.log("Result for Location " + i);
console.log("--------------------------");
console.log("\tLatitude: " + locations[i].latitude.toFixed(2));
console.log("\tLongitude: " + locations[i].longitude.toFixed(2));
console.log("\tMean Rainfall: " + result.mean.toFixed(2) + "cm");
console.log("\tMedian Rainfall: " + result.median.toFixed(2) + "cm");
console.log("\tStandard Dev.: " + result.standard_deviation.toFixed(2) + "cm");
console.log("\tNumber Samples: "+ result.n + "\n");
});
}
// locations 是采样信息,该函数返回空,结果通过回调处理
rainfall.calculate_results_sync(locations, print_rain_results);
console.log("JavaScript program has completed.")
Addon实现
只给出了同步调用,其他参数转换和数据计算和之前的例子一样。
void CalculateResultsSync(const v8::FunctionCallbackInfo<v8::Value>&args) {
Isolate* isolate = args.GetIsolate();
std::vector<location> locations;
std::vector<rain_result> results;
// 参数转换 js -》 C++
Local<Array> input = Local<Array>::Cast(args[0]);
unsigned int num_locations = input->Length();
for (unsigned int i = 0; i < num_locations; i++) {
locations.push_back(unpack_location(isolate, Local<Object>::Cast(input->Get(i))));
}
// 计算
results.resize(locations.size());
std::transform(locations.begin(), locations.end(), results.begin(), calc_rain_stats);
// 参数转换 C++ -》 js
Local<Array> result_list = Array::New(isolate);
for (unsigned int i = 0; i < results.size(); i++ ) {
Local<Object> result = Object::New(isolate);
pack_rain_result(isolate, result, results[i]);
result_list->Set(i, result);
}
// 回调
Local<Function> callback = Local<Function>::Cast(args[1]);
Handle<Value> argv[] = { result_list };
callback->Call(isolate->GetCurrentContext()->Global(), 1, argv);
std::cerr << "Returning from C++ now" << std::endl;
args.GetReturnValue().Set(Undefined(isolate));
}
void init(Handle <Object> exports, Handle<Object> module) {
NODE_SET_METHOD(exports, "calculate_results_sync", CalculateResultsSync);
}