Promise and Add-on, Think Asynchronously with Callback!
来源:互联网 发布:顶尖电子称软件下载 编辑:程序博客网 时间:2024/05/14 16:43
Normally, when writing an Add-on, we could code like this:
// Somewherevoid doSomething(std::string& str) { str = "Hello, world";}/// The implementation of add-onstatic void fork(const FunctionCallbackInfo<Value>& args) { Isolate* iso = args.GetIsolate(); /// Do something doSomething(str); /// Callback Local<Value> val = args[3]; // Assuming the forth arguments is the callback function. if (val->IsFunction()) { Local<Function> func = Function::Cast(val); func->Call(iso->GetCurrentContext()->Global(), Integer::New(iso, 0x1234)); }} // end of fork
The above code works fine unless Promise
involved. The notorious segment fault
will occur. Because the Promise.resolve
will probably come back from a different thread, so some changes must be made:
/// Turn our processing into async// Define the prototype of callback.using callback = boost::function<void(int, const std::string&)>;typedef struct { std::string value; callback cb;} async_struc;AsyncWorker<async_struc> async_worker;void doSomething(std::string& arg, const callback& cb { async_struc* data = new async_struc(); data.value = arg; data.cb = cb; async_worker.post(data, [&](async_struc* x) { // Do the work. x->value += "Hello, world!"; }, [&](async_struc* x, bool canceled) { x->cb(canceled ? -1 : 0, x->value); });}
When crossing thread boundary, we have to wrap JavaScript object with Persistent
. But v8
forbids us using explicit ctor
of Persistent
. An alternative is using a structure to hold the Persistent
wrapped object and pass a structure pointer to make lambda expression capture it.
The structure looks like :
typedef struct { std::string value; //<! The value came from arguments. Persistent<Function> cb;} js_callback_info_t;
Also, following v8
reference, we should get current Isolate
object under different threads. A HandleScope
is needed too.
Isolate* asyncIso = Isolate::GetCurrent();HandleScope scope(asyncIso);
Now rewrite the js add-on method:
static void fork(const FunctionCallbackInfo<Value>& args) { Isolate* iso = args.GetIsolate(); // Get string argument String::Utf8Value utf8str(args[0]); std::string str(*utf8str); /// Save the callback information Local<Value> val = args[3]; // Assuming the forth arguments is the callback function. js_callback_info_t* cb_info = new js_callback_info(); cb_info->value = str; cb_info->cb.Reset(iso, Local<Function>::Cast(val); doSomething(str, [&, cb_info](int err, const std::string& res) mutable { Isolate* asyncIso = Isolate::GetCurrent(); HandleScope scope(asyncIso); Local<Function> func = Local<Function>::New(asyncIso, cb_info->cb); Local<Value> params[] = { Integer::New(asyncIso, err), String::NewUtf8(asyncIso, res.c_str()) }; func->Call(asyncIso->GetCurrentContext()->Global(), 2, params); // Dispose persistent object func->cb.Reset(); // Release the memory allocated before delete cb_info; });} // end of fork
Now the Add-on is Promise-ready.
Good luck!
- Promise and Add-on, Think Asynchronously with Callback!
- Working with promise and generators
- Promise with fetch and post
- Loading Images Asynchronously on iPhone using NSInvocationOperation
- 6.13 Running Tasks Asynchronously with Operations
- add Admob with Cocos2d-x on iOS
- Add Linkage between Team and MatchDay, with remarks and bonus
- 6.7 Executing Non-UI Related Tasks Asynchronously with GCD
- Working with BeforeProperties and AfterProperties on SPItemEventReceiver
- Working with Fragments and ViewPager on Android
- 并发编程 Promise, Future 和 Callback
- koa学习笔记----callback,promise,generator
- 并发编程 Promise, Future 和 Callback
- 并发编程 Promise, Future 和 Callback
- 异步javascript,callback、Promise?我们用Generator!
- [转]并发编程 Promise, Future 和 Callback
- 用Promise优化nodejs的callback hell
- Promise.js with AJAX
- float失真问题
- [LeetCode] 205. Isomorphic Strings
- 怎样防止App在后台运行,点击应用桌面图标重新启动?
- 微信小程序开发 --安装篇
- spark读取json,parquet文件
- Promise and Add-on, Think Asynchronously with Callback!
- 一张图说明servlet、servlet容器、web服务器、Tomcat之间的关系
- javascript之闭包详解
- 配置github以及上传本地项目至github
- windows下python安装Numpy、Scipy、matplotlib模块
- checkbox单选
- C++面试题(二)
- 直线向量方程
- 在Service中新开线程和直接新开线程的区别与意义