jQuery text animate help. Stop at last word - text

I found this code and it works great! But
how do I stop it when it reaches the last word?
(function(){
// List your words here:
var words = [
'awesome',
'incredible',
'cool',
'fantastic'
], i = 0;
setInterval(function(){
$('#changerificwordspanid').fadeOut(function(){
$(this).html(words[i=(i+1)%words.length]).fadeIn();
});
// 2 seconds
}, 2000);
})();

before you start the code for the animation check if there is a word in the array and if not stop the interval.
(function(){
// List your words here:
var words = [
'awesome',
'incredible',
'cool',
'fantastic'
], i = 0;
var interval = setInterval(function(){
if(i+1 < words.length) {
$('#changerificwordspanid').fadeOut(function(){
$(this).html(words[i=(i+1)%words.length]).fadeIn();
});
} else {
window.clearIntervall(interval);
}
// 2 seconds
}, 2000);
})();
clear interval can be found here:
http://de.selfhtml.org/javascript/objekte/window.htm#clear_interval

You can avoid to interval by do this, It's will be continue adding word smoothly.
(function(){
// List your words here:
var words = [
'awesome',
'incredible',
'cool',
'fantastic'
], i = 0;
(function loop(){
$('#changerificwordspanid').fadeOut(function(){
// send the loop function to fadeIn, It will exec when fadeIn complete
$(this).html(words.shift()).fadeIn(loop);
});
})();
})();
If you also need 2 sec delay, after each fadeIn effect completed. do this
(function(){
// List your words here:
var words = [
'awesome',
'incredible',
'cool',
'fantastic'
], i = 0;
(function loop(){
$('#changerificwordspanid').fadeOut(function(){
// settimeout for 2 sec before called loop
$(this).html(words.shift()).fadeIn(function(){
setTimeout(loop, 2000);
});
});
})();
})();

Related

Return is happening before the loop finishes execution

I am using for loop and return is happening before the loop finishes execution. I cant use .Map method because i have some conditions in between and want to break the loop in between.
const getCompanies = async(searchURL,reqBody) => {
const html = await rp(baseURL + searchURL);
businessMap = cheerio('a.business-name', html);
for(var i=0; i < businessMap.length; i++) {
linkNew = baseURL + businessMap[i].attribs.href;
const innerHtml = await rp(linkNew);
..
...My Code with conditions here
.....
......
......
values.push( [a,b,c,d,e,f]);
}
return values
}
I see 2 options here:
You have a break that gets executed where it is says My code with conditions here.
rp doesn't return a Promise.
As for the second option, here's a quick code to show you that the final line of an async function gets executed only when all awaits are finished:
const delay = (ms) => {
return new Promise(r => {
setTimeout(r, ms);
console.log("delayed", ms);
});
}
const run = async () => {
for (var i = 0; i < 3; i++) {
await delay(1000);
}
console.log("finished");
}
run();

How to make the setTimeout sequential for multiple database updates?

I am updating database fields by using setTimeout(). So when the updates are multiple what happens is the the last primary key is used for all the updates. How do I run the setTimeout() function sequentially. Below is the portion of code which does that.
for( var i = 0; i < req.body.devicelist.length; i++) { //running for loop for multiple elements
var data = JSONPARSE.toObject(req.body);
mac_id = req.body.devicelist[i];
data.mac_id = mac_id;
var gateway_config;
for (let j = 0; j < gateways_config.length; j++) { //code for fetching specific element. IGNORE
if(gateways_config[j].latest_config.mac_id == mac_id){
gateway_config = gateways_config[j]
break;
}
gateway_config = undefined
}
await syncConfig(req.body,gateway_config, req.decoded.id);
..........
..........
}
syncConfig(body,gateway,user_id){
var jsonObj = body;
...
...
...
config_timeout_array[jsonObj.mac_id] = setTimeout(() => { //Causing problem
commandTimeout(jsonObj.org_id,jsonObj.mac_id)
}, 10000);
...
...
}
commandTimeout:(org_id, mac_id) =>{
console.log(mac_id); //prints same mac_id (the last in the array)
return gateway_model.findOneAndUpdate({ org_id: org_id, mac_id: mac_id }, { 'sync_sent': false }, {"new": true})
.then((updated_gateway) => {
...
...
...
}
}
config_timeout_array[jsonObj.mac_id] = setTimeout(() => { //Causing problem
commandTimeout(jsonObj.org_id,jsonObj.mac_id)
}, 10000);
Instead of doing the above logic directly, call a function and do it there. I don't know why but it worked!
seqTimeout(jsonObj.org_id,jsonObj.mac_id); //function call
seqTimeout(org_id,mac_id){
config_timeout_array[mac_id] = setTimeout(() => {
GatewayController.commandTimeout(org_id, mac_id);
}, COMMAND_TIMEOUT);
}

How to fix ProcessBar to the top line in Nodejs CLI?

The terminal out is:
but actually this is what I really want:
progressbar will alway be the fist line,and got a response,then show it at below.
anyway to fix that?
Nodejs:
var request = require('request');
var ProgressBar = require('progress');
var year=[14,15,16];
var month=[1,2,3,4,5,6,7];
var bar = new ProgressBar('Processing [:bar] :percent', {
complete: '=',
incomplete: '-',
width: 30,
total: year.length*month.length,
});
/*-------------------------------------*/
function init(year,month){
check(year,month);
}
function check(year,month){
var options = { method: 'POST',
url: 'http://dev.site/date.php',
formData:{year:year,month:month}
};
request(options, function (error, response, body) {
if (error) {
console.log(error);;
}
if (body=='A task #') {
bar.tick();
console.log('\n'+body+year+':'+month);
}else{
bar.tick();
}
})
}
/*-------------------------------------*/
for (var i = 0; i < year.length; i++) {
for (var n = 0; n < month.length; n++) {
init(year[i],month[n]);
}
}
Using ansi-escapes you may be able to do this.
Here's a standalone version:
const ProgressBar = require('progress');
const ansiEscapes = require('ansi-escapes');
const write = process.stdout.write.bind(process.stdout);
let bar = new ProgressBar('Processing [:bar] :percent', {
complete : '=',
incomplete : '-',
width : 30,
total : 100
});
// Start by clearing the screen and positioning the cursor on the second line
// (because the progress bar will be positioned on the first line)
write(ansiEscapes.clearScreen + ansiEscapes.cursorTo(0, 1));
let i = 0;
setInterval(() => {
// Save cursor position and move it to the top left corner.
write(ansiEscapes.cursorSavePosition + ansiEscapes.cursorTo(0, 0));
// Update the progress bar.
bar.tick();
// Restore the cursor position.
write(ansiEscapes.cursorRestorePosition);
// Write a message every 10 ticks.
if (++i % 10 === 0) {
console.log('Now at', i);
}
// We're done.
if (i === 100) {
process.exit(0);
}
}, 100);

About terminating a dynamically constructed sequence of promises

I wrote a script in Node that iterates over a large MongoDB collection, returning a certain number of documents at a time.
The collection has this simple format:
{
name: 'One',
data: '...'
},
{
name: 'Two',
data: '...'
},
...
I'm doing this job with the Q library, using a sequence of promises that get run one after the other:
'use strict';
var Q = require('q');
var monk = require('monk');
var CHUNK_SIZE = 100;
var LIMIT = 1000;
var collection = monk('localhost/dictionary').get('entries');
var promiseFactory = function (j) {
return function (result) {
if (undefined !== result) { // if result is undefined, we are at the first or last iteration.
if (result.length) {
for (var k = 0, max = result.length; k < max; k++) {
console.log(result[k].name); // print name
// ... do something with the document here...
}
} else { // no more documents, end of the iteration
return; // implicitely returns undefined
}
}
// returns CHUNK_SIZE documents, starting from the j-th document
return collection.find({}, { limit: CHUNK_SIZE, skip: j, sort: { name: 1 }});
};
};
var funcs = [];
for (var i = CHUNK_SIZE; i <= LIMIT; i += CHUNK_SIZE) {
funcs.push(promiseFactory(i));
}
var loop = Q.fcall(promiseFactory(0));
funcs.forEach(function (f) {
loop = loop.then(f);
});
The script works well and does achieve what it was designed to do.
However, I would like to improve it:
I'm hardcoding the number of documents in the collection (LIMIT). I would like to get rid of this variable and let the script detect when to stop.
I have a feeling that this approach may not be the most memory-efficient one. In my code, funcs.forEach() chains a lot of copies of the same function in one shot (to be exact LIMIT/CHUNK_SIZE copies). Since I'm working on a very large collection, I was wondering if there's a way to chain a new function only if there are still documents left, while running through the collection.
I think I found the solution to both problems. It is just a simple addition in promiseFactory() which I have highlighted below. Adding it here in the hope it is useful to someone:
var promiseFactory = function (j) {
return function (result) {
if (undefined !== result) { // if result is undefined, we are at the first or last iteration.
if (result.length) {
for (var k = 0, max = result.length; k < max; k++) {
console.log(result[k].en + ' - ' + result[k].le);
}
} else { // no more entries, end of the iteration
return; // implicitely returns undefined
}
}
///////////////// CHANGE HERE ////////////////////////
return entries.find({}, { limit: CHUNK_SIZE, skip: j, sort: { en: 1 }}).then(promiseFactory(j + CHUNK_SIZE));
///////////////////// END ////////////////////////////
};
};

how to use process.hrtime to get execution time of async function

I am triing to get execution time of async function. Seemingly I can use process.hrtime for this. I created simple example:
console.log("starting");
var start = process.hrtime();
console.log("start");
console.log(start);
setTimeout(function(){
console.log("HELLO");
var end = process.hrtime();
console.log("end");
console.log(end);
}, 1000);
It outputs
starting
start
[ 131806, 731009597 ]
HELLO
end
[ 131807, 738212296 ]
But I don't understand where is exectuion time in miliseconds? I expect to get 1000 ms in this example.
Got it:
console.log("starting");
var start = process.hrtime();
console.log("start");
console.log(start);
setTimeout(function(){
console.log("HELLO");
var end = process.hrtime(start);
console.log("end");
console.log(end);
}, 1000);
Prints
starting
start
[ 132798, 207101051 ]
HELLO
end
[ 1, 7001730 ]
That means 1 second and 7001730 nanoseconds from start to end
Since Node 10.7.0, process.hrtime is marked as 'legacy', with the recommended method being process.hrtime.bigint. The documentation contains an example of how to use this method to time an operation:
const start = process.hrtime.bigint();
// 191051479007711n
setTimeout(() => {
const end = process.hrtime.bigint();
// 191052633396993n
console.log(`Benchmark took ${end - start} nanoseconds`);
// Benchmark took 1154389282 nanoseconds
}, 1000);
Just to add in case someone needs the execution time in ms:
console.log("starting");
var start = process.hrtime();
console.log("start");
console.log(start);
setTimeout(function(){
console.log("HELLO");
var end = process.hrtime(start); // end[0] is in seconds, end[1] is in nanoseconds
const timeInMs = (end[0]* 1000000000 + end[1]) / 1000000; // convert first to ns then to ms
console.log("timeInMs:", timeInMs);
}, 1000);
Here's a simple wrapper timing function for async functions:
// async function execution time wrapper
async function fnTime(fn, ...params) {
const start = process.hrtime()
const result = await fn(...params)
const end = process.hrtime(start)
console.log(
`[${fn.name}] Execution time:${(end[0] * 1000000000 + end[1]) /
1000000} ms`
)
return result
}
example usage (see this demo on repl.it):
// usage
const setTimeoutPromise = ms => new Promise(resolve => setTimeout(resolve, ms))
// example 2:
// get name from db
const db = {
async getUser(id){
// simulate wait for record retrival from db
await fnTime(setTimeoutPromise, 150)
return {
_id: id,
name: 'John Doe',
organisation: 'UN',
email: 'johndoe#un.org'
}
}
}
// test it
;(async function(){
const result = await fnTime(db.getUser, 'asfa98th4nfwef0qwrwef0')
console.log('result', result)
})()
// result:
// [setTimeoutPromise] Execution time:197.928094 ms
// [getUser] Execution time:199.480553 ms

Resources