DZone
Web Dev Zone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone > Web Dev Zone > JavaScript for C# developers: callbacks (part III)

JavaScript for C# developers: callbacks (part III)

Julian Bucknall user avatar by
Julian Bucknall
·
Apr. 02, 11 · Web Dev Zone · News
Like (0)
Save
Tweet
1.56K Views

Join the DZone community and get the full member experience.

Join For Free

in the previous two installments ( one , two ) we explored the use of callbacks through creating a mapp function for arrays (so called because the latest javascripts have a native map method already), and through creating a mapasync function where the work is done asynchronously rather than serially. the reason for this was so that we could avoid triggering the browser’s “script running a long time” warning and, also, more importantly, provide the user with a responsive ui.

risk photo © 2007 sputnik | more info (via: wylio ) in this final part i just want to tidy up the mapasync method. when i left it last time,the function would process each element using a delay. this is, in all probability, way too much work and way too slow. we could potentially do more work each cycle without inconveniencing the user and thereby reduce the number of delays we have to go through. but how much work? how long do we have? jakob nielsen says that

“ 0.1 second is about the limit for having the user feel that the system is reacting instantaneously, meaning that no special feedback is necessary except to display the result.”

ok, then, 100 milliseconds it is. actually, thinking about it, that leaves no time for maneuver and so i’ll go for half that for the mapasync method.

so, what we’d like to do is process as many elements as we can in 50 milliseconds (instead of just processing the one) and then recurse using a delay for the next batch. we therefore need the ability to time our processing.

javascript comes with the date class. if you new up a date, what you get is a variable containing the current date/time, much as datetime.now does in c# and .net. what we’ll do is get the start time and then start processing as many elements as possible. for each element we’ll process it, then get the current time. if the current time minus the start time is less than 50ms, round the loop we go again. unfortunately, we can’t just subtract one date from another, the minus operator only works for numbers. however all is not lost: if we convert a date to a number, we get the number of milliseconds from some base date. and to convert? just use the unary plus operator. here’s an example:

var start = +new date();
do {
// work
} while ((+new date() - start) < 50);

we get the current date/time as the number of milliseconds by newing up a date and then converting it to a number by use of the unary plus. we then enter a do..while loop, and continue round doing work while the current date/time minus the start time is less than 50. pretty easy, no?

incorporating it into the current version of mapasync is fairly mundane:

array.prototype.mapasync = function (process, done, context) {
var i = 0,
result = [],
last = this.length,
self = this,
processasync = function () {
var start = +new date();
do {
if (i in self) {
result[i] = process.call(context, self[i], i);
}
i++;
} while ((i < last) && (+new date() - start) < 50);
console.log("*"); // just for showing progress
if (i === last) {
done.call(context, result);
}
else {
processasync.delay(10);
}
};
processasync();
};


of course, there’s a bit more to that inner loop condition since we also want to break out if we manage to process the final element. i’ve thrown in a logging statement after the loop for now, just to show that we’re nicely chunking the work and still performing several delayed calls to processasync. we’ll delete it when we’ve shown it working.

of course, my little example of an 8-element array just isn’t going to cut the mustard with this new code, so let’s go for broke and use a 100,000 element array:

var myarray = [];
for (var i = 0; i < 100000; i++) {
myarray[i] = i;
}

myarray.mapasync(function (element, index) {
return "<" + index.tostring() + ": " + element.tostring() + ">";
}, function (a) {
console.log("done");
delete myarray;
});

all the completion callback does this time is to log “done” (printing the array will overload the console – i know because i did it) and delete the original array – it is fairly big after all. when i run this code in firebug, i get this:

*
undefined
*
*
*
*
*
*
*
*
*
done

again, the “undefined” at the top is firebug printing the return value of calling mapasync. as you can see, it chunked the 100,000 element array into 10 delayed calls, roughly 10,000 elements per call. or, if you like, i managed to process 10,000 elements in 50 milliseconds, which ain’t too shabby.

that’s it for this series on callbacks. i hope it proved useful. remember: if you want to use this maparray method (i use an mit license, so go for it), do take out the logging statement in the middle.

JavaScript Element

Published at DZone with permission of Julian Bucknall, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Top 20 Git Commands With Examples
  • Building a Kotlin Mobile App with the Salesforce SDK, Part 3: Synchronizing Data
  • A Guide to Understanding Vue Lifecycle Hooks
  • Data Visualization of Healthcare Expenses by Country Using Web Scraping in Python

Comments

Web Dev Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • MVB Program
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends:

DZone.com is powered by 

AnswerHub logo