GithubHelp home page GithubHelp logo

dtao / lazy.js Goto Github PK

View Code? Open in Web Editor NEW
6.0K 6.0K 269.0 4.05 MB

Like Underscore, but lazier

Home Page: http://danieltao.com/lazy.js/

License: MIT License

Ruby 0.99% JavaScript 87.74% CSS 4.99% HTML 6.29%

lazy.js's Introduction

Like Underscore, but lazier

Build Status Bower version NPM version

Lazy.js is a functional utility library for JavaScript, similar to Underscore and Lodash, but with a lazy engine under the hood that strives to do as little work as possible while being as flexible as possible.

It has no external dependencies, so you can get started right away with:

npm install lazy.js

(Note the package is called "lazy.js", with a dot.)

Or, if you're using Lazy.js in the browser:

<script type="text/javascript" src="lazy.js"></script>

<!-- optional: if you want support for DOM event and AJAX-based sequences: -->
<script type="text/javascript" src="lazy.browser.js"></script>

Now let's look at what you can do with Lazy.js. (For more thorough information, take a look at the API Docs.)

Introduction

Let's start with an array of objects representing people.

var people = getBigArrayOfPeople();

Suppose we're using this array to back some sort of search-as-you-type functionality, where users can search for people by their last names. Naturally we want to put some reasonable constraints on our problem space, so we'll provide up to 5 results at a time. Supposing the user types "Smith", we could therefore fetch results using something like this (using Underscore):

var results = _.chain(people)
  .pluck('lastName')
  .filter(function(name) { return name.startsWith('Smith'); })
  .take(5)
  .value();

This query does a lot of stuff:

  • pluck('lastName'): iterates over the array and creates a new (potentially giant) array
  • filter(...): iterates over the new array, creating yet another (potentially giant) array
  • take(5): all that just for 5 elements!

So if performance and/or efficiency were a concern for you, you would probably not do things that way using Underscore. Instead, you'd likely go the procedural route:

var results = [];
for (var i = 0; i < people.length; ++i) {
  if (people[i].lastName.startsWith('Smith')) {
    results.push(people[i].lastName);
    if (results.length === 5) {
      break;
    }
  }
}

There—now we haven't created any extraneous arrays, and we did all of the work in one iteration. Any problems?

Well, yeah. The main problem is that this is one-off code, which isn't reusable or particularly readable. If only we could somehow leverage the expressive power of Underscore but still get the performance of the hand-written procedural solution...


That's where Lazy.js comes in! Here's how we'd write the above query using Lazy.js:

var result = Lazy(people)
  .pluck('lastName')
  .filter(function(name) { return name.startsWith('Smith'); })
  .take(5);

Looks almost identical, right? That's the idea: Lazy.js aims to be completely familiar to JavaScript devs experienced with Underscore or Lodash. Every method from Underscore should have the same name and (almost) identical behavior in Lazy.js, except that instead of returning a fully-populated array on every call, it creates a sequence object with an each method.

What's important here is that no iteration takes place until you call each, and no intermediate arrays are created. Essentially Lazy.js combines all query operations into a "sequence" that behaves quite a bit like the procedural code we wrote a moment ago. (If you ever do want an array, simply call toArray on the resulting sequence.)

Of course, unlike the procedural approach, Lazy.js lets you keep your code clean and functional, and focus on solving whatever problem you're actually trying to solve instead of optimizing array traversals.

Features

So, Lazy.js is basically Underscore with lazy evaluation. Is that it?

Nope!

Indefinite sequence generation

The sequence-based paradigm of Lazy.js lets you do some pretty cool things that simply aren't possible with Underscore's array-based approach. One of these is the generation of indefinite sequences, which can go on forever, yet still support all of Lazy's built-in mapping and filtering capabilities.

Here's an example. Let's say we want 300 unique random numbers between 1 and 1000.

Lazy.generate(Math.random)
  .map(function(e) { return Math.floor(e * 1000) + 1; })
  .uniq()
  .take(300)
  .each(function(e) { console.log(e); });

Here's a slightly more advanced example: let's use Lazy.js to make a Fibonacci sequence.

var fibonacci = Lazy.generate(function() {
  var x = 1,
      y = 1;
  return function() {
    var prev = x;
    x = y;
    y += prev;
    return prev;
  };
}());

// Output: [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
fibonacci.take(10).toArray();

OK, what else?

Asynchronous iteration

You've probably seen code snippets before that show how to iterate over an array asynchronously in JavaScript. But have you seen an example with functional goodness like this?

Lazy.generate(Lazy.identity)
  .async(1000) // specifies a 1-second interval between each element
  .map(function(x) { return String.fromCharCode(x + 65); })
  .take(26)
  .each(function(char) { console.log(char); });

All right... what else?

Event sequences

With indefinite sequences, we saw that unlike Underscore and Lodash, Lazy.js doesn't actually need an in-memory collection to iterate over. And asynchronous sequences demonstrate that it also doesn't need to do all its iteration at once.

Now here's a really cool combination of these two features: with a small extension to Lazy.js (lazy.browser.js, a separate file to include in browser-based environments), you can apply all of the power of Lazy.js to handling DOM events. In other words, Lazy.js lets you think of DOM events as a sequence—just like any other—and apply the usual map, filter, etc. functions on that sequence.

Here's an example. Let's say we want to handle all mousemove events on a given DOM element, and show their coordinates in one of two other DOM elements depending on location.

// First we define our "sequence" of events.
var mouseEvents = Lazy(sourceElement).on("mousemove");

// Map the Event objects to their coordinates, relative to the element.
var coordinates = mouseEvents.map(function(e) {
  var elementRect = sourceElement.getBoundingClientRect();
  return [
    Math.floor(e.clientX - elementRect.left),
    Math.floor(e.clientY - elementRect.top)
  ];
});

// For mouse events on one side of the element, display the coordinates in one place.
coordinates
  .filter(function(pos) { return pos[0] < sourceElement.clientWidth / 2; })
  .each(function(pos) { displayCoordinates(leftElement, pos); });

// For those on the other side, display them in a different place.
coordinates
  .filter(function(pos) { return pos[0] > sourceElement.clientWidth / 2; })
  .each(function(pos) { displayCoordinates(rightElement, pos); });

Anything else? Of course!

String processing

Now here's something you may not have even thought of: String.match and String.split. In JavaScript, each of these methods returns an array of substrings. If you think about it, this often means doing more work than necessary; but it's the quickest way (from a developer's standpoint) to get the job done.

For example, suppose you wanted the first five lines of a block of text. You could always do this:

var firstFiveLines = text.split("\n").slice(0, 5);

But of course, this actually splits the entire string into every single line. If the string is very large, this is quite wasteful.

With Lazy.js, we don't need to split up an entire string just to treat it as a sequence of lines. We can get the same effect by wrapping the string with Lazy and calling split:

var firstFiveLines = Lazy(text).split("\n").take(5);

This way we can read the first five lines of an arbitrarily large string (without pre-populating a huge array) and map/reduce on it just as with any other sequence.

Similarly with String.match: let's say we wanted to find the first 5 alphanumeric matches in a string. With Lazy.js, it's easy!

var firstFiveWords = Lazy(text).match(/[a-z0-9]+/i).take(5);

Piece of cake.

Stream processing

Lazy.js can wrap streams in Node.js as well.

Given any Readable Stream, you can wrap it with Lazy just as with arrays:

Lazy(stream)
  .take(5) // Read just the first 5 chunks of data read into the buffer.
  .each(processData);

For convenience, specialized helper methods for dealing with either file streams or HTTP streams are also offered. (Note: this API will probably change.)

// Read the first 5 lines from a file:
Lazy.readFile("path/to/file")
  .lines()
  .take(5)
  .each(doSomething);

// Read lines 5-10 from an HTTP response.
Lazy.makeHttpRequest("http://example.com")
  .lines()
  .drop(5)
  .take(5)
  .each(doSomething);

In each case, the elements in the sequence will be "chunks" of data most likely comprising multiple lines. The lines() method splits each chunk into lines (lazily, of course).


This library is experimental and still a work in progress.

lazy.js's People

Contributors

aaronjrubin avatar adhertz avatar amilajack avatar appsforartists avatar bnjmnt4n avatar dtao avatar ebenpack avatar flyyang avatar frozencow avatar gyeates avatar hden avatar jeduden avatar jeroenverfallie avatar kkirsche avatar l8d avatar mikeal avatar olsonpm avatar patrickjs avatar peterdavehello avatar phidias avatar qiemem avatar seanhussey avatar talater avatar twotonebytes avatar weakish avatar ymichael avatar zippy1981 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lazy.js's Issues

Support object streams

You appear to be assuming that the readable stream you get is going to give you strings (and has a setEncoding method) but it should just take whatever the body is.

var lazy = require('lazy.js')
  , request = require('request')
  , jsonstream = require('JSONstream')
  ;

var json = request('http://isaacs.iriscouch.com/registry/_all_docs?include_docs=true')
  .pipe(jsonstream.parse(['rows', true]))

lazy(json).each(function (x) {console.log(x)})

results in

/Users/mikeal/Documents/git/npmetrics/node_modules/lazy.js/lazy.node.js:42
    stream.setEncoding(encoding);
           ^
TypeError: Object #<Stream> has no method 'setEncoding'
    at /Users/mikeal/Documents/git/npmetrics/node_modules/lazy.js/lazy.node.js:42:12
    at Sequence.StreamedSequence.openStream (/Users/mikeal/Documents/git/npmetrics/node_modules/lazy.js/lazy.node.js:22:3)
    at Sequence.StreamedSequence.each (/Users/mikeal/Documents/git/npmetrics/node_modules/lazy.js/lazy.node.js:35:8)
    at Object.<anonymous> (/Users/mikeal/Documents/git/npmetrics/index.js:9:12)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)

Lazy(object).length() ?

To obtain object keys length with lazy.js, I do

var len = Lazy(object).keys().toArray().length;

However, I want to write simply

var len = Lazy(object).length();

Does this make sense? or any philosophy we should not have this?

Thx

Joining multiple wrapped array?

Consider the following example:

var foo = Lazy([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

var even = foo.filter(function(d) {
  return (d % 2) === 0;
}).map(function(d) {
  return d * 10;
});

var odd = foo.filter(function(d) {
  return (d % 2) !== 0;
}).map(function(d) {
  // do something else;
});

var result = Lazy([even, odd]).invoke('toArray').flatten().toArray();

The problem is that invoking toArray brakes the lazy evaluation chain. Is there a better way to join multiple wrapped array?

Breaking change 0.x release: Sequence.define

0.2 init no loger takes parent as first argument

0.1 version

lazy.Sequence.define 'indexBy',
  init: (@parent, @keyFn) ->
    if typeof @keyFn is 'string'
      keyStr = @keyFn
      @keyFn = (item) -> item[keyStr]
  each: (fn) ->
    for value in @parent
      fn([@keyFn(value), value])

0.2 version

lazy.Sequence.define 'indexBy',
  init: (@keyFn) ->
    if typeof @keyFn is 'string'
      keyStr = @keyFn
      @keyFn = (item) -> item[keyStr]
  each: (fn) ->
    for value in @parent
      fn([@keyFn(value), value])

Sorry about CoffeeScript but I think you get the gist.

Write a wrapper for I/O streams in Node

This is an obvious use case.

Just need to read up on the IO libraries in Node, learn how they work, and figure out how to adapt them to Lazy's API (just like I already did w/ DOM events).

Lazy.lines.getIterator() not working

This example prints nothing.

var Lazy = require('lazy.js');

var it = Lazy.readFile("log.txt")
            .lines()
            .getIterator();

while(it.moveNext()){
    console.log(it.current());
}

Altough this example works correctly:

var Lazy = require('lazy.js');

Lazy.readFile("log.txt")
        .lines()
        .each(function(line){
            console.log(line);
        });

I'm using version 0.3.1 installed from npm.

Licence

I could not find which licence this library is under.

Optimize ArrayWrapper

I'm pretty sure I can squeeze even more performance out of the simple cases if I re-implement map, filter, etc. on ArrayWrapper.prototype to cut out the overhead of get(i) and length(). Just a hypothesis, though—need to get around to validating that.

Async-Improvement

Hello Dan,
my name is Dustin Deus I´m software engineer from Germany. I like your array library lazy.js.I have one observation when I use lazy.js with NodeJs you use for async operations the "setTimeout" function with a variable timeout. This works very well when somebody want a timeout but if you just want a fast async iteration I recommend you to use the much more efficient method "process.nextTick" and for all DOM stuff you can use the setImmediate API with great fallbacks. https://github.com/NobleJS/setImmediate
I think this change will increase you library in async speed very well.

Write a LINQ wrapper to expose a friendlier API to .NET devs

I'm thinking something like:

Lazy.linq(array)
  .Select(x)
  .Where(y)
  .Distinct()
  .ToArray();

Which should translate to:

Lazy(array)
  .map(x)
  .filter(y)
  .uniq()
  .toArray();

Or maybe that's kind of pointless? (The only reason would be to make it a bit more familiar to someone looking for another "LINQ for JavaScript" tool.)

The rationale of initial Sequence#initial

API Doc
initial Sequence#initial
Creates a new sequence comprising all but the last N elements of this sequence.

Why exclude the last element?
The rationale is needed to the doc. Thanks.

lazily merging

i've had great success with Lazy so far (yea!!) but have gotten stuck on trying to find a way to do a "_.merge" in Lazy
http://lodash.com/docs#merge

it's actually an array of objects i need to merge into a single object with Lazy

btw, your string-table is working great!! thanks again!!

Broken sequence.{min,max} for empty mapped sequence

When an empty sequence is mapped to access a specific property, min and max break.

Lazy([]).map(function(d) { return d.foo; }).min()
Lazy([]).map(function(d) { return d.foo; }).max()

both throw following error:

TypeError: Cannot read property 'foo' of undefined

Whereas they should return undefined (like Lazy([]).{min,max}() correctly do).

Allow Setting Value Later

It'd be great to be able to create pure functional behaviors, and then later apply them to values. A jsfiddle of the below.

Something along the lines of this:

var makePeople = Lazy([]).map(function(s){
    var parts = s.split(" ");
    return {
        first: parts[0],
        last: parts[1],
        full: s
    };
});

var data = ["John Doe", "Ann Robljsakld"];
makePeople.of(data);

The result would be:

[
  {
    "first": "John",
    "last": "Doe",
    "full": "John Doe"
  },
  {
    "first": "Ann",
    "last": "Robljsakld",
    "full": "Ann Robljsakld"
  }
] 

Suggested implementation:

Lazy.Sequence.prototype.of = function(source) {
    var previousSource = this.source, returnValue;
    this.source = source;

    if (this.startsWith) {
        returnValue = this.toString();
    }
    else if (this.pairs) {
        returnValue = this.toObject();
    }
    else {
        returnValue = this.toArray();    
    }

    this.source = previousSource;
    return returnValue;
};

`each` method should pass index as well as value

Just like Underscore/Lo-Dash.

However, I'm not sure the benefit of passing the collection as the third parameter is very valuable in this case.

Also, I doubt providing the option to bind to a specific this is very important. If and when people ask for that down the road, I can add it then.

Implement object methods

There are plenty of methods that currently only work on arrays that should also work on objects. each, map, and filter, would be an obvious start.

Work on performance of uniq

Lazy.js gets creamed on this particular method right now (unless you exit early, e.g. w/ take).

Inexcusable!

Allow 2-arity Array.sort-style comparators to be passed into sortBy functions

Hi, firstly thanks for such a great library. I really love it.

I would like to provide Array.sort-style 2-arity comparator functions to sortBy functions as this method of comparing elements allows the greatest amount of flexibility (for example, reverse sorting of string elements, sorting of different types elements in the same array, or multi-level sorting)

By 2-arity comparator functions, I mean ones which take 2 arguments and allow the implementation to return 0, -1 or +1 depending on the order, for example:

function compare(a, b) {
  if (a is less than b by some ordering criterion)
     return -1;
  if (a is greater than b by the ordering criterion)
     return 1;
  // a must be equal to b
  return 0;
}

Backbone and some other libraries check the length of the comparator function in order to decide whether to use simple 1-arity function or comparator-style 2-arity function.

Let me know what you think: I'm happy to have a crack at doing the work via a pull-request, but would like your feedback on the implementation first.

Poor IE performance

IE10's results were disappointing. I'm kinda bummed by my Android4.3 (Samsung Note2) results also, but not too worried. http://jsperf.com/chain-vs-pipe/6 Reduced results:

        Generic |  Lazy | Lo-Dash chain
Chrome31  2,153 | 4,109 | 4,862
Firefox24   784 | 1,005 | 1,027
IE10      1,710 |   909 | 2,910
Android4.3  272 |   523 |   701
IE8 VM       30 |    36 |    42

However, IE10 performance seems to be better against competition in another 1 width array test.

Edit: I tried the MS suppled VirtualBox for testing IE8. Even after turning on VT-x in my bios, & hacking the image's Registry to avoid IE script warning, it still performed worse than I remember IE8 ran on the same machine (which was bad). I would throw out my IE8 VM's results.

License banner in distributed library files

Can you please add a banner to libraries (lazy.js, lazy.browser.js and lazy.node.js), just like jQuery does:

/*!
 * jQuery JavaScript Library v2.0.3
 * http://jquery.com/
 *
 * Includes Sizzle.js
 * http://sizzlejs.com/
 *
 * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors
 * Released under the MIT license
 * http://jquery.org/license
 *
 * Date: 2013-07-03T13:30Z
 */

or like allong.es does:

/*! http://github.com/raganwald/allong.es (c) 2012-2013 Reg Braithwaite MIT Licensed */

Note importance of /*! comment form. These comments could be optionally skipped by minifiers.

It'd be pretty useful for recognizing copyright and license in single JS file, assembled from vendor libraries and application's code

Breaking changes in 0.x release: "You cannot wrap null, undefined, or primitive values using Lazy"

Thanks a ton for keeping up the good work! We've just pulled 0.2 release and found that I breaks many cases that we use.

The culprit is https://github.com/dtao/lazy.js/blob/master/lazy.js#L94 and the You cannot wrap null, undefined, or primitive values using Lazy error. This check makes API not compatible with 0.1 release.

Our general use pattern is like so:

results = MongoCollection.find(...)
results = lazy(results).do().stuff().toArray()

Often results would be null based on the find() query but because we used lazy 0.1 we would always have at least an empty array in the end.

0.2 breaks this pattern.

What are the thoughts behind it and is this a final call on the API?

How to use toObject?

Didn't find anywhere with examples using toObject, how to create a proper object from the sequence?

first method with a StringLikeSequence

Based on the documentation, I expect that:

lazy('this is a string').first()

Will return the string 't'.

Instead, it returns another StringLikeSequence. So then I try:

lazy('this is a string').first().toString()

And I get the string 'this is a string'.

Am I misunderstanding the contract of first here?

Async iteration

a better model for async iteration might be something like the async library's version where the iterator function can deal with async things, so for a contrived example say I wanted to download files with the scheme http://fakestuff.nope/blahblah0.json, http://fakestuff.nope/blahblah1.json,... being able to do something like

var result = Lazy
    .generate(function(a){
        return a;//am I missing an easier way to do this?
    })
    .async()
    .map(function(value,index,callback){
        $.ajax('http://fakestuff.nope/blahblah'+value+'.json').then(callback);
    })
    .take(5)

though that doesn't actually work without some sort of promise implementation so something like

Lazy
    .generate(function(a){return a;})
    .async()
    .map(function(value,index,callback){
        $.ajax('http://fakestuff.nope/blahblah'+value+'.json').then(callback);
    })
    .take(5,function(result){
        //do stuff with result
    });

while we're at it the .async method could be used for how many to do at a time

Lazy
    .generate(function(a){return a;})
    .async(3)//3 at a time
    .map(function(value,index,callback){
        $.ajax('http://fakestuff.nope/blahblah'+value+'.json').then(callback);
    })
    .take(5,function(result){
        //do stuff with result
    });

this could be pretty helpful if in the example we only wanted one of them, knew it was under 500, and had some value

Lazy
    .range(0,500)
    .async()
    .map(function(value,index,callback){
        $.ajax({url:'http://fakestuff.nope/blahblah'+value+'.json').then(callback);
    })
    .find(function(a){
        return a.someKey === someValue;
    })

as far as I can tell the idea of an async iteration here is that you don't care about the return of the iterator.

You could also do this with promises instead of callbacks, which would probably be more inline with the library but that's a different can of worms.

No way to handle errors from aync processes

If an error occurs with an asynchronous data provider (such as a stream), there's no way (as far as i can tell) to intercept that error. Normally, libraries like async.js handle this with an argument passed to a callback.

Create a Node benchmark runner

The benchmarking code is highly coupled to the docs page right now and so can only run in a browser. This should be refactored so that the same perf specs can run in a browser or on Node (preferably with some nice console output).

Calling map() on an ObjectLikeSequence takes a function with (value, key) parameters instead of (tuple) parameters?

In the most recent version of lazy.js, we were able to use it like this:

lazy({a:1, b:2, c:3})
  .map(function(tuple) { return tuple.join('='); })
  .toArray()

  // => ["a=1", "b=2", "c=3"]

Seems like now the pattern is:

lazy({a:1, b:2, c:3})
  .map(function(value, key) { return [key, value].join('='); })
  .toArray()

  // => ["a=1", "b=2", "c=3"]

This makes some sense, but it doesn't seem to be documented/tested anywhere? It's also possible we're missing something. Either way, this broke a lot of our code :( (early adopter woes, I know.)

FWIW, we use lazy with coffeescript, where the tuple syntax actually says a lot about the underlying representation of the lazy sequence we're working with. Example:

lazy(a:1, b:2, c:3)
  .map ([key, value]) ->
    "#{key}=#{value}"
  .toArray()

  # => ["a=1", "b=2", "c=3"]

Thanks again for the library, it's extremely useful and keeps us lazy.

Implement lazy JSON parsing

I'm pretty sure this is possible, and I'm totally going to do it.

Alternately, if somebody else wants to implement it, I would gladly give you push access.

Benchmark jquery

I like your benchmark personally and I would like to see a comparison to jquery as well. Now I know jquery does not exactly fulfill the same purpose, but there is some common ground and a comparison of whats comparable between jquery and the others would be nice.

Is it possilble to have Lazy.events (Event sequences) for value change?

lazy.js is one of the best project I've ever found.
This library integrates undersocre/linq.js and RxJS with lazy evaluation advantage where I feel that a clean and complete implementation of Functional/Declarative programming paradigm is deployed; All the JS programmers should learn from this.
Thank you, Dan Tao.

Having said that, I have a question:
Basically, I want to bind javascript value with DOM element behavior.

To monitor myval change event, I could code something like:

var monitor = function()
{
  if(myval != myval0)
  {
      triggerEach(); // function to manipulate DOM 
  }
  myval0 = myval;
}
var tid = setInterval(function()
{
    monitor();
},100);

Is it possilble to have Lazy.events like this??

HttpStreamSequence.prototype.openStream won't work

The callback that is passed in expects to be called with a stream, but the function executes http.get(URL.parse(this.url), callback); which will call it with a http.IncomingMessage which is not a stream.

Furthermore, openStream is not a real async function for files or StreamedSequence in general -- the callback is called on the same tick, which can cause some weird side-effects. Using process.nextTick() to delay calling the callback seems to break the tests, however.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.