nodejs 回调函数(nodejs回调函数返回值)

前言

前两节我们讲述了node插件的基础入门,以及需要的环境, 这一节我们来尝试写一个复杂一点的插件, 通过Node-Api 实现插件导出普通函数和回调函数。

环境安装

安装bindings依赖 以及 node-addon-api 依赖

相关package.json文件内容如下

 {
  "name": "my-node-addon",
  "version": "0.0.0",
  "description": "nodejs addon nan",
  "main": "hello.js",
  "private": true,
  "dependencies": {
    "bindings": "~1.2.1",
    "node-addon-api": "^1.0.0"
  },
  "scripts": {
    "test": "node hello.js"
  },
  "gypfile": true
}

编写插件代码 main.cpp

这个C++源文件实现了 函数 Add和回调函数 CallbackAdd

#include <napi.h>

/**
 * 加法
 * @param info
 * @return
 */
Napi::Value Add(const Napi::CallbackInfo& info) {
    //获取上下文环境
    Napi::Env env = info.Env();
    //如果参数少于2
    if (info.Length() < 2) {
        //js中丢出类型异常
        Napi::TypeError::New(env, "Wrong number of arguments")
                .ThrowAsJavaScriptException();
        return env.Null();
    }
    //如果存在参数不是number类型
    if (!info[0].IsNumber() || !info[1].IsNumber()) {
        Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException();
        return env.Null();
    }
    //转换成dobule 类型参数
    double arg0 = info[0].As<Napi::Number>().DoubleValue();
    double arg1 = info[1].As<Napi::Number>().DoubleValue();
    //返回number类型
    Napi::Number num = Napi::Number::New(env, arg0 + arg1);
    return num;
}

/**
 * 回调函数增加
 * @param info
 */
void CallbackAdd(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();
    //如果参数少于2
    if (info.Length() < 3) {
        //js中丢出类型异常
        Napi::TypeError::New(env, "Wrong number of arguments")
                .ThrowAsJavaScriptException();
        return;
    }
    //如果存在参数不是number类型
    if (!info[0].IsNumber() || !info[1].IsNumber()) {
        Napi::TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException();
        return;
    }
    //第三个参数不是函数
    if (!info[2].IsFunction()) {
        Napi::TypeError::New(env, "Wrong callback").ThrowAsJavaScriptException();
        return;
    }
    auto v1 = info[0].As<Napi::Number>().DoubleValue();
    auto v2 = info[1].As<Napi::Number>().DoubleValue();
    Napi::Function cb = info[2].As<Napi::Function>();
    cb.Call(env.Global(),{Napi::Number::New(env,v1+v2)});
}
//模块注册函数,用于每个自定义模块注册
Napi::Object Init(Napi::Env env, Napi::Object exports) {
    //暴露方法
    exports.Set(Napi::String::New(env, "add"), Napi::Function::New(env, Add));
    exports.Set(Napi::String::New(env,"addCallback"), Napi::Function::New(env, CallbackAdd));
    return exports;
}

NODE_API_MODULE(addon, Init)

编写调用index.js文件

var addon = require('bindings')('my_node_addon.node');

console.log(addon)
console.log('This should be eight:', addon.add(3,12))
addon.addCallback(1,2,(ret)=>{
    console.log('add callback should ret 3:' ,ret);
});

try{
    addon.addCallback(1,(ret)=>{
        console.log('add callback should ret 3:' ,ret);
    });
}catch (ex){
    console.log(ex.toString())
}

try{
    addon.addCallback(1,1,2);
}catch (ex){
    console.log(ex.toString())
}

编译插件

sudo npm install 
sudo node-gyp configure
sudo env CC=Clang CXX=CLang++  node-gyp build

编译后运行index.js

  node index.js 

nodejs 回调函数(node 回调函数步骤)nodejs 回调函数(node 回调函数步骤)

至此我们就完成了通过C++编写node.js 插件 并且导出 普通函数 和 回调函数 供js调用。