node.js and mysql - need data from select to update - mysql

my problem is that i try to write a callback method in node.js
for different mysql selects and updates. The update commands must wait
for the data from the select to work with it. but sometimes they cant,
cause the vars are "undefined". maybe i need a callback function to make
that work. In the following example there is a jQuery animation to wait
for before the callback starts. But how can i solve that with an mysql
command:
function mySandwich(param1, param2, callback) {
alert('Started eating my sandwich.\n\nIt has: ' + param1 + ', ' + param2);
$('#sandwich').animate({
opacity: 0
}, 5000, function() {
// Animation complete.
if (callback && typeof(callback) === "function") {
callback();
}
});
}
mySandwich('ham', 'cheese', function() {
alert('Finished eating my sandwich.');
});
I hope someone can explain me that.
Best regards

I would recommend looking at async.js it allows for things to run in series, or parallel, and pass information on to either a final callback function or to the next function.

Related

Gulp only runs dependent task but not main task [duplicate]

I'm working through a pluralsight course on gulp. John Papa is demonstrating how to inject a function that deletes existing css files, into the routine that compiles the new ones.
The callback on the del function is not firing. The del function is running, file are deleted, I see no error messages. If I call the callback manually it executes, so looks like the function is in tact. So I am wondering what would cause del not to want to execute the callback.
delete routine:
function clean(path, done) {
log('cleaning ' + path);
del(path, done); // problem call
}
The 'done' function is not firing, but it does if I change the code to this:
function clean(path, done) {
log('cleaning ' + path);
del(path);
done();
}
Which, of course, defeats the intended purpose of waiting until del is done before continuing on.
Any ideas at to what's going on would be appreciated.
for reference (in case relevant):
compile css function:
gulp.task('styles', ['clean-styles'], function(){
log('compiling less');
return gulp
.src(config.less)
.pipe($.less())
.pipe($.autoprefixer({browsers:['last 2 versions', '> 5%']}))
.pipe(gulp.dest(config.temp));
});
injected clean function:
gulp.task('clean-styles', function(done){
var files = config.temp + '/**/*.css';
clean(files, done);
});
UPDATE
If anyone else runs into this, re-watched the training video and it was using v1.1 of del. I checked and I was using 2.x. After installing v 1.1 all works.
del isn't a Node's command, it's probably this npm package. If that's the case it doesn't receive a callback as second parameter, instead it returns a promise and you should call .then(done) to get it called after the del finishes.
Update
A better solution is to embrace the Gulp's promise nature:
Change your clean function to:
function clean(path) {
return del(path); // returns a promise
}
And your clean-styles task to:
gulp.task('clean-styles', function(){
var files = config.temp + '/**/*.css';
return clean(files);
});
As of version 2.0, del's API changed to use promises.
Thus to specify callback you should use .then():
del('unicorn.png').then(callback);
In case you need to call it from a gulp task - just return a promise from the task:
gulp.task('clean', function () {
return del('unicorn.png');
});
Checking the docs for the del package it looks like you're getting mixed up between node's standard callback mechanism and del's, which is using a promise.
You'll want to use the promise API, with .then(done) in order to execute the callback parameter.
Node and javascript in general is currently in a bit of a state of flux for design patterns to handle async code, with most of the browser community and standards folks leaning towards promises, whereas the Node community tends towards the callback style and a library such as async.
With ES6 standardizing promises, I suspect we're going to see more of these kinds of incompatibilities in node as the folks who are passionate about that API start incorporating into node code more and more.

How to send WebSocket events from blocking operation? (Design advice needed)

I use Mojolicious WebSocket to establish server-client messaging protocol.
There is long-time operation on server and I want update its progress on client-side.
In several points on server-side code I call $web_socket->send(...) and process it on client-side ws.onmessage = function (event) {...};
Everything work fine, but not in realtime: all messages has received by client at one big bulk list and only after whole server-side script has finished.
Server-side logic:
some_computation1();
$web_socket->send('computation1 end');
...
some_computation15();
$web_socket->send('computation15 end');
...
some_computation100();
$web_socket->send('computation100 end. All ok!');
Client-side:
ws = new WebSocket(url);
ws.onmessage = function (event) {
$('#log_view').append('<p>' + event.data + '</p>');
};
ws.onopen = function (event) {
...
};
ws.onclose = function (event) {
...
};
There is two example how to make it using one of two modules:
Mojo::IOLoop::ReadWriteFork
Mojo::IOLoop::ForkCall
To run it execute command:
perl perl_ws_long_blocking_operation.pl daemon
Upd.
If you have many long blocking operations you should use Mojo::IOLoop::Delay:
Example of many long blocking operation
To run it execute command:
morbo perl_ws_many_long_blocking_operations.pl
I found this works for me: Mojo::IOLoop->one_tick;
some_computation1();
$web_socket->send('computation1 end');
Mojo::IOLoop->one_tick;
UPD: or may be it will be better to separate long operation in background thread ('fork' or 'delay').

gulp.watch - To return or not return

The official documentation for gulpjs/gulp has a sample gulpfile.js which provides a watch task that has no return statement:
gulp.task('watch', function() {
gulp.watch(paths.scripts, ['scripts']);
gulp.watch(paths.images, ['images']);
});
That approach fits my needs, because I want to watch over multiple sets of files with different tasks associated to each of them.
But I've found in the community a few bold statements saying that gulp.watch should be returned, such as this one, that proposes the following code:
gulp.task('watch', function() {
return gulp.watch('./public/resources/jsx/project/*.js',['application'])
});
I understand that tasks should return, so that other tasks using them as part of their workflow are able to act accordingly to their async nature, but for the special case of a watch task, which is always the last in a list of tasks, there might make sense not to return it, making it possible to have multiple watches.
Does that make sense? Can I safely omit the return from my watch task in order to be able to have multiple instances of gulp.watch in it?
I prefer all task have return statement. Otherwise you can read a false "Finished watch".
When task are complex, it is not possible create a single watch for a several pattern of files. In this cases, my solution is based on to create a supergroup task called "watch" that depends on single watches with its return statements.
gulp.task("watch", [
"watch-css",
"watch-js",
"watch-inject-html"
]);
gulp.task("watch-css", function() {
return gulp.watch(sources.css, ["css"]);
});
gulp.task("watch-js", function() {
return gulp.watch(sources.js, ["js"]);
});
gulp.task("watch-inject-html", function() {
return gulp.watch(sources.inject, ["inject-html"]);
});
For gulp4 you can do this:
gulp.task('watch:images', gulp.parallel(
function () { return gulp.watch(SRC_DIR+'/*', gulp.task('images:copy')); },
function () { return gulp.watch(SRC_DIR+'/svg/**/*', gulp.task('images:svg')); },
function () { return gulp.watch(SRC_DIR+'/backgrounds/**/*', gulp.task('images:backgrounds')); },
function () { return gulp.watch(SRC_DIR+'/heads/**/*', gulp.task('images:heads')); }
));
However the anonymous functions inside gulp.parallel will report as <anonymous> in gulp output.
You can give the functions names and they will show up in gulp output instead of anonymous.
gulp.task('watch:images', gulp.parallel(
function foobar1 () { return gulp.watch(SRC_DIR+'/*', gulp.task('images:copy')); },
function foobar2 () { return gulp.watch(SRC_DIR+'/svg/**/*', gulp.task('images:svg')); },
function foobar3 () { return gulp.watch(SRC_DIR+'/backgrounds/**/*', gulp.task('images:backgrounds')); },
function foobar4 () { return gulp.watch(SRC_DIR+'/heads/**/*', gulp.task('images:heads')); }
));
However it seems that return gulp.watch(/* ... */) is not ideal. When watching if you hit CTRL-C you get a nice big error about those watch tasks not completing.
It seems like if you have a stream you are supposed to return the stream.
e.g. return gulp.src(...).pipe()
...but if you are doing something async or don't have a stream you should be calling the callback instead of returning something.
Would be happy to be pointed to the relevant docs for this (return vs callback) as I didn't see a clear explanation in the gulp docs I read. I tried going all callback (no returning streams) and ran into other issues...but possibly they were caused by something else.
Dealing with multiple watches in a single task the following way doesn't report <anonymous> and also doesn't complain when you CTRL-C while watching. My understanding is that since the watch tasks are open-ended we just inform gulp that as far as gulp cares when it comes to making sure stuff runs in a specific order, these are started and gulp can move on.
gulp.task('watch:images', function (done) {
gulp.watch(SRC_DIR+'/*', gulp.task('images:copy'));
gulp.watch(SRC_DIR+'/svg/**/*', gulp.task('images:svg'));
gulp.watch(SRC_DIR+'/backgrounds/**/*', gulp.task('images:backgrounds'));
gulp.watch(SRC_DIR+'/heads/**/*', gulp.task('images:heads'));
return done();
});
I think you can omit return for watch task. I also don't support structures that has multiple watches. More over you are only going to use watch task on development environment, so go ahead and ignore return for watch task.

Sequential promises in ES6 JavaScript aren't working

I'm trying to understand the es6 Promises. As I understood, they can be chained to be executed sequentially. It does not work in by case.
console.log("Started");
function doStuff(num, timeout) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
console.log("now " + num);
resolve();
}, timeout);
});
}
doStuff(1, 3000).then(doStuff(2, 2000)).then(doStuff(3, 1000));
However the output is:
$ node test
Started
now 3
now 2
now 1
I was expecting the reverse order. I do understand why it gets like this, they are all queued up and finishes in the "reverse" order.
But the thing is, I thought that the second was not executed until the first was finished and so on. What am I missing?
If you write it like this, the 3 calls to doStuff will start when you write the line. You have to write it like this :
doStuff(1, 3000).then(function() {
return doStuff(2, 2000);
}).then(function() {
return doStuff(3, 3000);
});
As loganfsmyth said, is you are doing ES6, you can also use arrow functions :
doStuff(1, 3000).then(() => doStuff(2, 2000)).then(() => doStuff(3, 3000));
Isn't there a typo ? you should chain the then part to the doStuff call, perhaps like this:
doStuff(1, 3000).then(function(){
doStuff(2, 2000).then(function(){
doStuff(3, 1000);
});
});
timeouts in javascript are asynchronous. The way you have it written now, all three promises are executed in order, and the timeout function just queues up the code inside of it to run after a certain time duration. A timeout's execution doesn't mean its resolution; it's considered "done" when its internal code is queued. That's why the second and third promises don't have to wait for the line "console.log("now " + num);" to execute before being kicked off.
See this answer https://stackoverflow.com/a/19626821/2782404 for some background on asynchronous tasks in js.

Code execution step by step (synchronous)

I just have two (see below) lines of code in my index.html. I want to execute the first line BEFORE the second line will be executed. How can I do/ensure that? Currently, "undefined" will be apprear in the console for dataDB, because the function getDataFunction() takes some time.
var dataDB = getDataFunction(afterDate, toDate, afterTime, toTime);
console.log("Content of dataDB: " + dataDB);
Probably an easy question for you :-) I appreciate your help!
UPDATE: getDataFunction()
This function just get some data (collection+json) from a server with d3 (data driven document)...The parameters are used to identify the data of interest (time frame).
function getDataFunction(afterDate, toDate, afterTime, toTime){
d3.json("http://server...", function(error, data){
if(error) {
console.log(error);
} else {
console.log(data);
dataDB = data.collection.items;
console.log(dataDB);
}
});
}
D3 api reference
It says in the api reference the post is indeed done asychronously, thus the execution of the rest of the code proceeds (in this case console.log) there are no decent ways to make javascript wait. The best thing to do is to redesign it that your callback function takes care of whatever needs to come next.