Execute method on other thread and get result to JS
Posted:
Sun Jun 27, 2021 12:36 pm
by prsolucoes
Hi,
How to execute a method on other thread and get result to Javascript?
Im using this example in mind (i don't know if it is the best example):
https://chromium.googlesource.com/chrom ... ing-a-taskI want call C++ function from javascript like im already do here:
https://github.com/paulo-coutinho/cef-s ... me.vue#L94But i want now execute a long time function without block browser and return the result/callback to javascript function. Something like this:
- Code: Select all
var result = MyApp.longTask("my param 1", "my param 2");
console.log(result);
// or
MyApp.longTask("my param 1", "my param 2").then((result) => {
console.log(result);
}).catch((error) => {
console.log(error);
});
Can anyone help me?
Thanks.
Re: Execute method on other thread and get result to Javascr
Posted:
Sun Jun 27, 2021 9:13 pm
by prsolucoes
Hi,
I tried this:
- Code: Select all
#include "main/v8/AppExtension.hpp"
#include <chrono>
#include <ctime>
#include <iostream>
namespace v8
{
class NotifyTask : public CefTask
{
public:
NotifyTask(CefRefPtr<CefV8Context> context, CefRefPtr<CefV8Value> callback) : callback(callback), context(context) {}
void Execute() override
{
CefV8ValueList args;
args.push_back(CefV8Value::CreateString("12345"));
callback->ExecuteFunctionWithContext(context, NULL, args);
}
private:
CefRefPtr<CefV8Value> callback;
CefRefPtr<CefV8Context> context;
IMPLEMENT_REFCOUNTING(NotifyTask);
};
bool AppV8ExtensionHandler::Execute(const CefString &name, CefRefPtr<CefV8Value> object, const CefV8ValueList &arguments, CefRefPtr<CefV8Value> &retval, CefString &exception)
{
if (name == "getStuffMessage")
{
retval = CefV8Value::CreateString("A stuff message from C++");
return true;
}
else if (name == "getCurrentTime")
{
std::time_t now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
char buf[100] = {0};
std::strftime(buf, sizeof(buf), "%Y-%m-%d %r", std::localtime(&now));
std::string value = std::string(buf);
retval = CefV8Value::CreateString(value.c_str());
return true;
}
else if (name == "longTask")
{
retval = CefV8Value::CreateNull();
if (arguments.size() == 1 && arguments[0]->IsFunction())
{
CefRefPtr<CefV8Value> func = arguments[0];
CefRefPtr<CefV8Context> context = CefV8Context::GetCurrentContext();
CefRefPtr<CefTaskRunner> taskRunner = CefTaskRunner::GetForCurrentThread();
taskRunner->PostTask(new NotifyTask(context, func));
return true;
}
else
{
exception = "Function Not Supported";
}
return false;
}
return false;
}
void AppV8ExtensionHandler::init()
{
// register a V8 extension with the below JavaScript code that calls native methods implemented in the handler
std::string code =
""
"var MyApp;"
"if (!MyApp) {"
" MyApp = {};"
"}"
""
"(function() {"
" MyApp.getStuffMessage = function() {"
" native function getStuffMessage();"
" return getStuffMessage();"
" };"
" MyApp.getCurrentTime = function() {"
" native function getCurrentTime();"
" return getCurrentTime();"
" };"
" MyApp.longTask = function(params) {"
" native function longTask(params);"
" return longTask(params);"
" };"
""
"})();";
CefRegisterExtension("v8/app", code, new v8::AppV8ExtensionHandler());
}
} // namespace v8
But when i try call i only receive error:
- Code: Select all
longTask() {
MyApp.longTask()
.then((result) => {
this.message = result;
})
.catch((e) => {
this.message = "Error: " + e;
});
},
longTask2() {
MyApp.longTask(function (result) {
this.message = result;
});
},
Can anyone help me?
Re: Execute method on other thread and get result to JS
Posted:
Mon Jun 28, 2021 12:18 am
by prsolucoes
After a lot of search on forum, slack, google etc - it don't work.
I put my sample code here:
https://github.com/paulo-coutinho/cef-s ... ension.cppIf anyone help me, please post here.
Re: Execute method on other thread and get result to JS
Posted:
Mon Jun 28, 2021 11:18 am
by magreenblatt
JavaScript native bindings can only be used on the main renderer process thread. You will need to use some other approach for the execution (like WebWorker, async execution, etc) that then calls back to the native bindings on the main thread.
Re: Execute method on other thread and get result to JS
Posted:
Mon Jun 28, 2021 3:29 pm
by prsolucoes
magreenblatt wrote:JavaScript native bindings can only be used on the main renderer process thread. You will need to use some other approach for the execution (like WebWorker, async execution, etc) that then calls back to the native bindings on the main thread.
Hi,
Ok @magreenblatt,
But do you have any example?
I make one try but didnt work:
https://github.com/paulo-coutinho/cef-s ... ension.cppI searched all places and don't find any answer about it that make me understand how i can do it.
Re: Execute method on other thread and get result to JS
Posted:
Mon Jun 28, 2021 5:11 pm
by magreenblatt
You can find examples of async JS bindings
here.
Re: Execute method on other thread and get result to JS
Posted:
Mon Jun 28, 2021 7:00 pm
by prsolucoes
magreenblatt wrote:You can find examples of async JS bindings
here.
I already read it 234343 times.
But don't understand how it works. Can you help me?
Re: Execute method on other thread and get result to JS
Posted:
Tue Jun 29, 2021 9:25 pm
by prsolucoes
Hi,
I made an example and it is working:
https://github.com/paulo-coutinho/cef-s ... inding.cppBut i have a question: Im storing the browser callback in the request, because when request finish i have the browser callback. There is any problem?
https://github.com/paulo-coutinho/cef-s ... Client.cppThanks.
Re: Execute method on other thread and get result to JS
Posted:
Tue Jun 29, 2021 9:53 pm
by magreenblatt
What type of object is the browser callback? Any V8 objects need to be released by the time the associated context is released (OnContextReleased called).
Re: Execute method on other thread and get result to JS
Posted:
Wed Jun 30, 2021 3:48 pm
by prsolucoes
magreenblatt wrote:What type of object is the browser callback? Any V8 objects need to be released by the time the associated context is released (OnContextReleased called).
https://github.com/paulo-coutinho/cef-s ... nt.cpp#L10Browser Callback Is
- Code: Select all
CefRefPtr<CefMessageRouterBrowserSide::Callback> browserCallback
Request Callback Is:
- Code: Select all
typedef base::Callback<void(CefRefPtr<CefMessageRouterBrowserSide::Callback> /* browserCallback */, CefURLRequest::ErrorCode /*errorCode*/, const std::string & /*downloadData*/)> RequestCallback;
There is nothing related to V8 here, only binding objects. Im not sure about store browser callback that is the callback of binding.
What do you think?