Re: Re: Proposal: Conditional `catch` in Promises

2018-04-24 Thread Ayush Gupta
We could potentially provide the same functionality in `try/catch` by
extending the signature of `catch` to

```js
try {

} catch(, ) {

}
```

If `` evaluates to truthy, invoke the `catch` block,
otherwise don't.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Proposal: Allow Promise callbacks to be removed

2018-04-24 Thread Cyril Auburtin
Strange no one mentioned `Promise.race` which would do the job (ex:
https://github.com/mo/abortcontroller-polyfill/blob/master/src/abortableFetch.js#L77
)

2018-04-24 22:40 GMT+02:00 kai zhu :

> here's a simple (60 sloc), zero-dependency/zero-config, high-performance
> express-middleware for serving files, that can broadcast a single
> fs.readFile() operation to multiple server-requests.  the entire standalone
> program (including emulated express-server and client-side stress-testing)
> is under 200 sloc, and written entirely with glue-code and
> recursive-callbacks (similar to how one would go about writing an awk
> program).
>
> honestly, there's a surprising amount of high-level stuff you can get done
> in javascript using just glue-code, instead of resorting to complicated
> “reusable” classes / promises / generators
>
>
>
>
> ```js
> /*
>  * example.js
>  *
>  * this zero-dependency example will demo a simple (60 sloc),
> high-performance express-middleware
>  * that can broadcast a single fs.readFile() operation to multiple
> server-requests
>  *
>  *
>  *
>  * example usage:
>  * $ node example.js
>  *
>  * example output:
>  * [server] - listening on port 1337
>  * [client] - hammering file-server for 1000 ms with client-request "
> http://localhost:1337/example.js;
>  * [server] - broadcast 10083 bytes of data from task
> fs.readFile("example.js") to 352 server-requests in 229 ms
>  * [server] - broadcast 10083 bytes of data from task
> fs.readFile("example.js") to 459 server-requests in 296 ms
>  * [server] - broadcast 10083 bytes of data from task
> fs.readFile("example.js") to 642 server-requests in 299 ms
>  * [server] - broadcast 10083 bytes of data from task
> fs.readFile("example.js") to 353 server-requests in 166 ms
>  * [server] - broadcast 10083 bytes of data from task
> fs.readFile("example.js") to 1 server-requests in 1 ms
>  * [server] - handled 1807 server-file-requests total
>  * [client] - made 2100 client-requests total in 1022 ms
>  * [client] - (1807 client-requests passed)
>  * [client] - (293 client-requests failed)
>  *
>  * finished running stress-test
>  * feel free to continue playing with this file-server
>  * (e.g. $ curl http://localhost:1337/example.js)
>  * or press "ctrl-c" to exit
>  */
>
> /*jslint
> bitwise: true,
> browser: true,
> maxerr: 4,
> maxlen: 200,
> node: true,
> nomen: true,
> regexp: true,
> stupid: true
> */
> (function () {
> 'use strict';
> var local;
> local = {};
>
> local.middlewareFileServer = function (request, response,
> nextMiddleware) {
> /*
>  * this express-middleware will serve files in an optimized manner by
>  * piggybacking multiple requests for the same file onto a single
> readFileTask
>  * 1. if readFileTask with the given filename exist, then skip to step
> 4.
>  * 2. if requested filename does not exist, then goto nextMiddleware
>  * 3. if readFileTask with the given filename does not exist, then
> create it
>  * 4. piggyback server-request onto readFileTask with the given
> filename
>  * 5. broadcast data from readFileTask to all piggybacked
> server-requests
>  * 6. cleanup readFileTask
>  */
> var fileExists, filename, modeNext, onNext, timeStart;
> onNext = function (error, data) {
> modeNext += 1;
> switch (modeNext) {
> case 1:
> // init timeStart
> timeStart = Date.now();
> // init readFileTaskDict
> local.readFileTaskDict = local.readFileTaskDict || {};
> // init serverRequestsTotal
> local.serverRequestsTotal = local.serverRequestsTotal || 0
> // get filename from request
> filename = require('url').parse(request.url).pathname;
> // security - prevent access to parent directory, e.g.
> ../users/john/.ssh/id_rsa
> filename = require('path').resolve('/', filename).slice(1);
> // init fileExists
> fileExists = true;
> // 1. if readFileTask with the given filename exist, then
> skip to step 4.
> if (local.readFileTaskDict[filename]) {
> modeNext += 2;
> onNext();
> return;
> }
> local.readFileTaskDict[filename] = [];
> require('fs').exists(filename, onNext);
> break;
> case 2:
> fileExists = error;
> // 2. if requested filename does not exist, then goto
> nextMiddleware
> if (!fileExists) {
> modeNext = Infinity;
> }
> onNext();
> break;
> case 3:
> // 3. if readFileTask with the given filename does not
> exist, then create it
> 

Re: Proposal: Allow Promise callbacks to be removed

2018-04-24 Thread kai zhu
here's a simple (60 sloc), zero-dependency/zero-config, high-performance 
express-middleware for serving files, that can broadcast a single fs.readFile() 
operation to multiple server-requests.  the entire standalone program 
(including emulated express-server and client-side stress-testing) is under 200 
sloc, and written entirely with glue-code and recursive-callbacks (similar to 
how one would go about writing an awk program).

honestly, there's a surprising amount of high-level stuff you can get done in 
javascript using just glue-code, instead of resorting to complicated “reusable” 
classes / promises / generators





```js
/*
 * example.js
 *
 * this zero-dependency example will demo a simple (60 sloc), high-performance 
express-middleware
 * that can broadcast a single fs.readFile() operation to multiple 
server-requests
 *
 *
 *
 * example usage:
 * $ node example.js
 *
 * example output:
 * [server] - listening on port 1337
 * [client] - hammering file-server for 1000 ms with client-request 
"http://localhost:1337/example.js;
 * [server] - broadcast 10083 bytes of data from task fs.readFile("example.js") 
to 352 server-requests in 229 ms
 * [server] - broadcast 10083 bytes of data from task fs.readFile("example.js") 
to 459 server-requests in 296 ms
 * [server] - broadcast 10083 bytes of data from task fs.readFile("example.js") 
to 642 server-requests in 299 ms
 * [server] - broadcast 10083 bytes of data from task fs.readFile("example.js") 
to 353 server-requests in 166 ms
 * [server] - broadcast 10083 bytes of data from task fs.readFile("example.js") 
to 1 server-requests in 1 ms
 * [server] - handled 1807 server-file-requests total
 * [client] - made 2100 client-requests total in 1022 ms
 * [client] - (1807 client-requests passed)
 * [client] - (293 client-requests failed)
 *
 * finished running stress-test
 * feel free to continue playing with this file-server
 * (e.g. $ curl http://localhost:1337/example.js)
 * or press "ctrl-c" to exit
 */

/*jslint
bitwise: true,
browser: true,
maxerr: 4,
maxlen: 200,
node: true,
nomen: true,
regexp: true,
stupid: true
*/
(function () {
'use strict';
var local;
local = {};

local.middlewareFileServer = function (request, response, nextMiddleware) {
/*
 * this express-middleware will serve files in an optimized manner by
 * piggybacking multiple requests for the same file onto a single 
readFileTask
 * 1. if readFileTask with the given filename exist, then skip to step 4.
 * 2. if requested filename does not exist, then goto nextMiddleware
 * 3. if readFileTask with the given filename does not exist, then create it
 * 4. piggyback server-request onto readFileTask with the given filename
 * 5. broadcast data from readFileTask to all piggybacked server-requests
 * 6. cleanup readFileTask
 */
var fileExists, filename, modeNext, onNext, timeStart;
onNext = function (error, data) {
modeNext += 1;
switch (modeNext) {
case 1:
// init timeStart
timeStart = Date.now();
// init readFileTaskDict
local.readFileTaskDict = local.readFileTaskDict || {};
// init serverRequestsTotal
local.serverRequestsTotal = local.serverRequestsTotal || 0
// get filename from request
filename = require('url').parse(request.url).pathname;
// security - prevent access to parent directory, e.g. 
../users/john/.ssh/id_rsa
filename = require('path').resolve('/', filename).slice(1);
// init fileExists
fileExists = true;
// 1. if readFileTask with the given filename exist, then skip 
to step 4.
if (local.readFileTaskDict[filename]) {
modeNext += 2;
onNext();
return;
}
local.readFileTaskDict[filename] = [];
require('fs').exists(filename, onNext);
break;
case 2:
fileExists = error;
// 2. if requested filename does not exist, then goto 
nextMiddleware
if (!fileExists) {
modeNext = Infinity;
}
onNext();
break;
case 3:
// 3. if readFileTask with the given filename does not exist, 
then create it
require('fs').readFile(filename, function (error, data) {
modeNext = Infinity;
onNext(error, data);
});
onNext();
break;
case 4:
// 4. piggyback server-request onto readFileTask with the given 
filename
local.readFileTaskDict[filename].push(response);
break;
default:
// 5. 

Re: Accessing (n)th key from an object

2018-04-24 Thread Cyril Auburtin
just try it and see

https://repl.it/@caub/obj-vs-map-perf

2018-04-24 20:29 GMT+02:00 somonek :

> Thanks, hat's probably what I'll do.
>
> I was also thinking looking at @Augusto's approach that if you replace the
> object with a Map you can iterate as Augusto mentioned
> const [firstProp, secondProp, ...othersKeys] = myMap;
> and the order of items should not be a worry.
>
> Any comments on Map's performance in such a case?
>
> On Tue, Apr 24, 2018 at 8:22 PM, T.J. Crowder <
> tj.crow...@farsightsoftware.com> wrote:
>
>> On Tue, Apr 24, 2018 at 7:07 PM, Jordan Harband  wrote:
>> > Regardless of what's in the spec, relying on objects having an order
>> among
>> > their properties violates the conceptual mental model of objects: a bag
>> of
>> > unordered key/value pairs.
>> >
>> > If you want to convert an array - the best way to preserve order - into
>> an
>> > object for "performance" reasons, then you may also want to preserve an
>> > array of IDs so that ordering can be relied upon.
>>
>> Absolutely agree. As I said originally, relying on the order of the
>> properties in the object is almost always a bad idea.
>>
>> @somonek, an object with an array of keys is probably your best
>> solution. Wrap it up in an object with an API that all of the code
>> updating it can use, so you don't have consistency issues. You could
>> even give it an iterator. :-)
>>
>> -- T.J. Crowder
>>
>
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Accessing (n)th key from an object

2018-04-24 Thread somonek
Thanks, hat's probably what I'll do.

I was also thinking looking at @Augusto's approach that if you replace the
object with a Map you can iterate as Augusto mentioned
const [firstProp, secondProp, ...othersKeys] = myMap;
and the order of items should not be a worry.

Any comments on Map's performance in such a case?

On Tue, Apr 24, 2018 at 8:22 PM, T.J. Crowder <
tj.crow...@farsightsoftware.com> wrote:

> On Tue, Apr 24, 2018 at 7:07 PM, Jordan Harband  wrote:
> > Regardless of what's in the spec, relying on objects having an order
> among
> > their properties violates the conceptual mental model of objects: a bag
> of
> > unordered key/value pairs.
> >
> > If you want to convert an array - the best way to preserve order - into
> an
> > object for "performance" reasons, then you may also want to preserve an
> > array of IDs so that ordering can be relied upon.
>
> Absolutely agree. As I said originally, relying on the order of the
> properties in the object is almost always a bad idea.
>
> @somonek, an object with an array of keys is probably your best
> solution. Wrap it up in an object with an API that all of the code
> updating it can use, so you don't have consistency issues. You could
> even give it an iterator. :-)
>
> -- T.J. Crowder
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Accessing (n)th key from an object

2018-04-24 Thread T.J. Crowder
On Tue, Apr 24, 2018 at 7:07 PM, Jordan Harband  wrote:
> Regardless of what's in the spec, relying on objects having an order among
> their properties violates the conceptual mental model of objects: a bag of
> unordered key/value pairs.
>
> If you want to convert an array - the best way to preserve order - into an
> object for "performance" reasons, then you may also want to preserve an
> array of IDs so that ordering can be relied upon.

Absolutely agree. As I said originally, relying on the order of the
properties in the object is almost always a bad idea.

@somonek, an object with an array of keys is probably your best
solution. Wrap it up in an object with an API that all of the code
updating it can use, so you don't have consistency issues. You could
even give it an iterator. :-)

-- T.J. Crowder
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Accessing (n)th key from an object

2018-04-24 Thread Jordan Harband
Regardless of what's in the spec, relying on objects having an order among
their properties violates the conceptual mental model of objects: a bag of
unordered key/value pairs.

If you want to convert an array - the best way to preserve order - into an
object for "performance" reasons, then you may also want to preserve an
array of IDs so that ordering can be relied upon.

On Tue, Apr 24, 2018 at 10:26 AM, T.J. Crowder <
tj.crow...@farsightsoftware.com> wrote:

> On Tue, Apr 24, 2018 at 5:58 PM, Augusto Moura 
> wrote:
> > Assuming `Object.keys` has the same order as a simple `for..in` (as
> stated
> > in
> > mdn)[https://developer.mozilla.org/en-US/docs/Web/
> JavaScript/Reference/Global_Objects/Object/keys]...
>
> We'll have to fix that page, the spec does not define the order in which
> `for-in` will enumerate property names. (It does define the order in which
> `Object.keys` will provide the property names, now, but not `for-in`.) That
> said, all modern and modern-ish implementations I've tested (to be fair,
> just V8, SpiderMonkey, Chakra, and IE11's JScript) do indeed follow the
> defined order with `for-in` as well, with an object's own properties coming
> before inherited ones - http://jsfiddle.net/arhbn3k2/1/ (IE11-friendly
> version without Symbols: http://jsfiddle.net/arhbn3k2/5/). (Provided I
> haven't screwed up that test.) But it's specifically *not* specified - from
> [EnumerateObjectProperties][1] (the op `for-in` uses to initialize its
> loop):
>
> > The mechanics **and order** of enumerating the properties **is not
> specified** but must conform to the rules specified below.
>
> *(my emphasis)* It says it has to use [[OwnPropertyKeys]] to get the own
> property keys at each level, but doesn't -- as far as I can tell -- define
> the sequence of own vs. inherited properties.
>
> `Object.entries` follows the order (own properties only):
>
> ```js
> const [first, second, ...rest] = Object.entries(obj);
> ```
>
> ...but I don't think that, or `keysIterator`, really helps somonek vs.
> what he's doing now (`Object.keys`).
>
> -- T.J. Crowder
>
> [1]: https://tc39.github.io/ecma262/#sec-enumerate-object-properties
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ECMA site down

2018-04-24 Thread Allen Wirfs-Brock
Chill, Ecma's ISP is dealing with it. Claims site was hacked

⁣Sent from BlueMail ​

On Apr 24, 2018, 11:24 AM, at 11:24 AM, Michael Theriot 
 wrote:
>It's in French now... 稜
>
>> On Apr 24, 2018, at 10:16 AM, T.J. Crowder
> wrote:
>>
>> For any ECMA members on the list; http://ecma-international.org
>appears to be down at present. It shows a message saying:
>>
>> > Account Suspended
>> >
>> > This Account has been suspended.
>> >
>> > Contact your hosting provider for more information.
>>
>> Reasonably certain that it's not talking about *my* account. :-) (Not
>least because I tried from three completely separate IPs on different
>networks, in two separate countries, in one case using `wget`, not a
>browser.)
>>
>> -- T.J. Crowder
>> ___
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>
>
>
>
>___
>es-discuss mailing list
>es-discuss@mozilla.org
>https://mail.mozilla.org/listinfo/es-discuss
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ECMA site down

2018-04-24 Thread Till Schneidereit
There was an issue with the site causing it to be down for maintenance.
There's no exact ETA for when it'll be restored, but the hope is that it'll
be soon.

On Tue, Apr 24, 2018 at 6:29 PM, T.J. Crowder <
tj.crow...@farsightsoftware.com> wrote:

> On Tue, Apr 24, 2018 at 5:24 PM, Michael Theriot
>  wrote:
> > It's in French now... 稜
>
> ...saying it's inaccessible, yeah. :-) Parts of it were back for a bit
> (and aren't anymore), they're clearly working on it. I just mentioned
> it in case it was an unexpected outage, but clearly someone's on it
> (now).
>
> -- T.J. Crowder
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Accessing (n)th key from an object

2018-04-24 Thread T.J. Crowder
On Tue, Apr 24, 2018 at 5:58 PM, Augusto Moura 
wrote:
> Assuming `Object.keys` has the same order as a simple `for..in` (as stated
> in
> mdn)[
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys].
..

We'll have to fix that page, the spec does not define the order in which
`for-in` will enumerate property names. (It does define the order in which
`Object.keys` will provide the property names, now, but not `for-in`.) That
said, all modern and modern-ish implementations I've tested (to be fair,
just V8, SpiderMonkey, Chakra, and IE11's JScript) do indeed follow the
defined order with `for-in` as well, with an object's own properties coming
before inherited ones - http://jsfiddle.net/arhbn3k2/1/ (IE11-friendly
version without Symbols: http://jsfiddle.net/arhbn3k2/5/). (Provided I
haven't screwed up that test.) But it's specifically *not* specified - from
[EnumerateObjectProperties][1] (the op `for-in` uses to initialize its
loop):

> The mechanics **and order** of enumerating the properties **is not
specified** but must conform to the rules specified below.

*(my emphasis)* It says it has to use [[OwnPropertyKeys]] to get the own
property keys at each level, but doesn't -- as far as I can tell -- define
the sequence of own vs. inherited properties.

`Object.entries` follows the order (own properties only):

```js
const [first, second, ...rest] = Object.entries(obj);
```

...but I don't think that, or `keysIterator`, really helps somonek vs. what
he's doing now (`Object.keys`).

-- T.J. Crowder

[1]: https://tc39.github.io/ecma262/#sec-enumerate-object-properties
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Accessing (n)th key from an object

2018-04-24 Thread Augusto Moura
Assuming `Object.keys` has the same order as a simple `for..in` (as stated
in mdn)[
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys],
we can already implement a function to build a iterator from object keys,
and then we can destruct or use others helpers to minimize the array
creation. Something like:

``` js
function* keysIterator(obj) {
  for (const key in obj) {
if (obj.hasOwnProperty(key)) {
  yield key;
}
  }
}
const obj = { foo: 12, bar: 89 };

// Using destructuring
const [firstProp, secondProp, ...othersKeys] = keysIterator(obj);

// Using some helper functions
const props = take(2, 10)(obj);
```

The discussion IMHO is if we need that as a built in helper (maybe
`Object.keysIterator()`), and if we need to extend it to `Object.values`
and `Object.entries`.

Em ter, 24 de abr de 2018 às 10:54, somonek  escreveu:

> Hi all,
>
> Assuming that
>
> const myObject = {
>   one: 123,
>   two: 456,
> };
>
> could
> myObject[in 0] === 'one' // true
>
> be a better alternative of
> Object.keys(myObject)[0]
>
> and
> myObject[in 3] === undefined
>
> without the need to convert all the object keys into an array, but
> directly accessing one.
>
> Best,
> Serghei
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
-- 
Augusto Moura
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ECMA site down

2018-04-24 Thread T.J. Crowder
On Tue, Apr 24, 2018 at 5:24 PM, Michael Theriot
 wrote:
> It's in French now... 稜

...saying it's inaccessible, yeah. :-) Parts of it were back for a bit
(and aren't anymore), they're clearly working on it. I just mentioned
it in case it was an unexpected outage, but clearly someone's on it
(now).

-- T.J. Crowder
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ECMA site down

2018-04-24 Thread Michael Theriot
It's in French now... 稜

> On Apr 24, 2018, at 10:16 AM, T.J. Crowder  
> wrote:
> 
> For any ECMA members on the list; http://ecma-international.org appears to be 
> down at present. It shows a message saying:
> 
> > Account Suspended
> >
> > This Account has been suspended.
> >
> > Contact your hosting provider for more information.
> 
> Reasonably certain that it's not talking about *my* account. :-) (Not least 
> because I tried from three completely separate IPs on different networks, in 
> two separate countries, in one case using `wget`, not a browser.)
> 
> -- T.J. Crowder
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Accessing (n)th key from an object

2018-04-24 Thread T.J. Crowder
On Tue, Apr 24, 2018 at 4:24 PM, Michael Luder-Rosefield
 wrote:
> I've found myself using that pattern, actually. Say you have multiple
> variables and want to pass one of them on to a function, which wants to know
> the value (of course) of that variable but also some kind of name to know
> which one was passed on.
>
> The easiest way to do this in one pass at the stage you pass it on is for
> the variable name to match the one needed later, and send it to the function
> as the object `{ whateverName }`.

On those rare occasions, the way I'd use would be `["whateverName",
whateverName]` (granted it's more verbose at the call site). That's
what `Object.entries` and `Map.prototype.entries` do, for instance,
and it's friendly to destructuring:

```js
function example([name, value]) {
console.log(`${name} = ${value}`);
}
example(["answer", 42]);
```

-- T.J. Crowder
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Accessing (n)th key from an object

2018-04-24 Thread Michael Luder-Rosefield
I've found myself using that pattern, actually. Say you have multiple
variables and want to pass one of them on to a function, which wants to
know the value (of course) of that variable but also some kind of name to
know which one was passed on.

The easiest way to do this in one pass at the stage you pass it on is for
the variable name to match the one needed later, and send it to the
function as the object `{ whateverName }`.

It does require, alas, more fiddling about to get the key/value pair from
the object after.

On Tue, 24 Apr 2018 at 15:19 T.J. Crowder 
wrote:

> On Tue, Apr 24, 2018 at 2:54 PM, somonek
>  wrote:
> > ...
> >
> > could
> > myObject[in 0] === 'one' // true
>
> What's the use case? Relying on the order of the properties in the object
> is almost always a bad idea (although if I read the current spec correctly,
> `Object.keys` is no longer exempt from order as it once was). The only time
> I've seen this done that seemed reasonable was when the object was known to
> have a single own enumerable property but that property's name was unknown
> (which was, in itself, an X/Y problem -- the real problem was why that name
> was unknown/varied at runtime).
>
> -- T.J. Crowder
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Accessing (n)th key from an object

2018-04-24 Thread T.J. Crowder
On Tue, Apr 24, 2018 at 4:06 PM, David Teller
 wrote:
>
> Doing this sounds pretty fragile. Do you have any guarantee that the
> order of fields is the same as the order of the array? Even if that's
> the case in your scenario, it's pretty uncommon.

If we make a couple of assumptions:

1. He's adding the properties to a newly-created object in array order
2. None of the keys is an [integer index][1]

...then yes, the order is guaranteed (even for `Object.keys`, nowadays
-- that wasn't true in ES2015, not sure when it changed and the ECMA
site is down so I can't check the 2016 or 2017 snapshots [note to
self: keep local copies!]).

Agreed it's not the best way to go about it, though. :-)

-- T.J. Crowder

[1]: https://tc39.github.io/ecma262/#sec-object-type
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Accessing (n)th key from an object

2018-04-24 Thread David Teller
Doing this sounds pretty fragile. Do you have any guarantee that the
order of fields is the same as the order of the array? Even if that's
the case in your scenario, it's pretty uncommon.

On 24/04/2018 16:41, somonek wrote:
> The use case is: 
> (long story short)
> 
> I have an array of items coming from an api. They're converted to an
> object having the ids as keys for faster access of single items and
> loaded to a global store. 
> Then in React.js and I want to render only the first 2 items with a "See
> more" that would render the rest of them. 
> It would be handy (and probably more performant when the object is big
> as in my case) to have:
> 
> const product1 = myItems[in 0];
> const product2 = myItems[in 1];
> 
> instead of converting everything to an array first and then accessing
> the first items by index.
> 
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Accessing (n)th key from an object

2018-04-24 Thread T.J. Crowder
In that use case, I'd just remember those two objects from when you
converted the array to an object, e.g.:

```js
const obj = Object.create(null);
for (const item of theArray) {
obj[item.key] = item;
}
const firstItems = theArray.slice(0, 2);
```

...then use `firstItems` for showing the first two. Also has the
advantage that you can easily change how many you show before the "See
more."

-- T.J. Crowder

On Tue, Apr 24, 2018 at 3:41 PM, somonek  wrote:
> The use case is:
> (long story short)
>
> I have an array of items coming from an api. They're converted to an object
> having the ids as keys for faster access of single items and loaded to a
> global store.
> Then in React.js and I want to render only the first 2 items with a "See
> more" that would render the rest of them.
> It would be handy (and probably more performant when the object is big as in
> my case) to have:
>
> const product1 = myItems[in 0];
> const product2 = myItems[in 1];
>
> instead of converting everything to an array first and then accessing the
> first items by index.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Accessing (n)th key from an object

2018-04-24 Thread somonek
The use case is:
(long story short)

I have an array of items coming from an api. They're converted to an object
having the ids as keys for faster access of single items and loaded to a
global store.
Then in React.js and I want to render only the first 2 items with a "See
more" that would render the rest of them.
It would be handy (and probably more performant when the object is big as
in my case) to have:

const product1 = myItems[in 0];
const product2 = myItems[in 1];

instead of converting everything to an array first and then accessing the
first items by index.




On Tue, Apr 24, 2018 at 4:18 PM, T.J. Crowder <
tj.crow...@farsightsoftware.com> wrote:

> On Tue, Apr 24, 2018 at 2:54 PM, somonek
>  wrote:
> > ...
> >
> > could
> > myObject[in 0] === 'one' // true
>
> What's the use case? Relying on the order of the properties in the object
> is almost always a bad idea (although if I read the current spec correctly,
> `Object.keys` is no longer exempt from order as it once was). The only time
> I've seen this done that seemed reasonable was when the object was known to
> have a single own enumerable property but that property's name was unknown
> (which was, in itself, an X/Y problem -- the real problem was why that name
> was unknown/varied at runtime).
>
> -- T.J. Crowder
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Accessing (n)th key from an object

2018-04-24 Thread T.J. Crowder
On Tue, Apr 24, 2018 at 2:54 PM, somonek
 wrote:
> ...
>
> could
> myObject[in 0] === 'one' // true

What's the use case? Relying on the order of the properties in the object
is almost always a bad idea (although if I read the current spec correctly,
`Object.keys` is no longer exempt from order as it once was). The only time
I've seen this done that seemed reasonable was when the object was known to
have a single own enumerable property but that property's name was unknown
(which was, in itself, an X/Y problem -- the real problem was why that name
was unknown/varied at runtime).

-- T.J. Crowder
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


ECMA site down

2018-04-24 Thread T.J. Crowder
For any ECMA members on the list; http://ecma-international.org appears to
be down at present. It shows a message saying:

> Account Suspended
>
> This Account has been suspended.
>
> Contact your hosting provider for more information.

Reasonably certain that it's not talking about *my* account. :-) (Not least
because I tried from three completely separate IPs on different networks,
in two separate countries, in one case using `wget`, not a browser.)

-- T.J. Crowder
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Accessing (n)th key from an object

2018-04-24 Thread Mike Samuel
On Tue, Apr 24, 2018 at 9:54 AM, somonek  wrote:

> Hi all,
>
> Assuming that
>
> const myObject = {
>   one: 123,
>   two: 456,
> };
>
> could
> myObject[in 0] === 'one' // true
>
> be a better alternative of
> Object.keys(myObject)[0]
>
> and
> myObject[in 3] === undefined
>
> without the need to convert all the object keys into an array, but
> directly accessing one.
>

Why is this something that warrants extra syntax and not an optimization
better left to sufficiently smart engines?
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Accessing (n)th key from an object

2018-04-24 Thread somonek
Hi all,

Assuming that

const myObject = {
  one: 123,
  two: 456,
};

could
myObject[in 0] === 'one' // true

be a better alternative of
Object.keys(myObject)[0]

and
myObject[in 3] === undefined

without the need to convert all the object keys into an array, but directly
accessing one.

Best,
Serghei
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Proposal: Allow Promise callbacks to be removed

2018-04-24 Thread Andrea Giammarchi
to be honest, I have solved already these cases through named promises and
the broadcast micro library I've mentioned.

```js
let shouldAsk = true;
function askForExpensiveTask() {
  if (shouldAsk) {
shouldAsk = false;
doExpensiveThing().then(r => broadcast.that('expensive-task', r));
  }
  return broadcast.when('expensive-task');
}
```

That gives me the ability to name any task I want and resolve those asking
for such tasks whenever these are available.

A further call to `broadcast.that('expensive-task', other)` would update
the resolved value and notify those that setup
`broadcast.all('expensive-task', callback)`, which you can also `.drop()`
at any time.

Yet, having a way to hook into these kind of flows in core would be great.

Regards


On Tue, Apr 24, 2018 at 12:40 PM, kai zhu  wrote:

> I see a simple scenario like the following one:
>
>- user asks for a very expensive task clicking section A
>- while it's waiting for it, user changes idea clicking section B
>- both section A and section B needs that very expensive async call
>- drop "going to section A" info and put "go to section B" to that
>very same promise
>- whenever resolved, do that action
>
> A caching mechanism to trigger only once such expensive operation would
> also work, yet it's not possible to drop "go into A" and put "go into B”
>
>
> for your scenario, what you want is a cacheable background-task, where you
> can piggyback B onto the task initiated by A (e.g. common-but-expensive
> database-queries that might take 10-60 seconds to execute).
>
> its generally more trouble than its worth to micromanage such tasks with
> removeListeners or make them cancellable (maybe later on C wants to
> piggyback, even tho A and B are no longer interested).  its easier
> implementation-wise to have the background-task run its course and save it
> to cache, and just have A ignore the results.  the logic is that because
> this common-but-expensive task was recently called, it will likely be
> called again in the near-future, so let it run  its course and cache the
> result.
>
> here's a real-world cacheable-task implementation for such a scenario, but
> it piggybacks the expensive gzipping of commonly-requested files, instead
> of database-queries [1] [2]
>
> [1] https://github.com/kaizhu256/node-utility2/blob/2018.1.13/
> lib.utility2.js#L4372 - piggyback gzipping of files onto a cacheable-task
> [2] https://github.com/kaizhu256/node-utility2/blob/2018.1.13/
> lib.utility2.js#L5872 - cacheable-task source-code
>
>
>
> ```js
> /*jslint
> bitwise: true,
> browser: true,
> maxerr: 4,
> maxlen: 100,
> node: true,
> nomen: true,
> regexp: true,
> stupid: true
> */
>
> local.middlewareAssetsCached = function (request, response,
> nextMiddleware) {
> /*
>  * this function will run the middleware that will serve cached
> gzipped-assets
>  * 1. if cache-hit for the gzipped-asset, then immediately serve it to
> response
>  * 2. run background-task (if not already) to re-gzip the asset and update
> cache
>  * 3. save re-gzipped-asset to cache
>  * 4. if cache-miss, then piggy-back onto the background-task
>  */
> var options;
> options = {};
> local.onNext(options, function (error, data) {
> options.result = options.result || local.assetsDict[request.
> urlParsed.pathname];
> if (options.result === undefined) {
> nextMiddleware(error);
> return;
> }
> switch (options.modeNext) {
> case 1:
> // skip gzip
> if (response.headersSent ||
> !(/\bgzip\b/).test(request.headers['accept-encoding']))
> {
> options.modeNext += 1;
> options.onNext();
> return;
> }
> // gzip and cache result
> local.taskCreateCached({
> cacheDict: 'middlewareAssetsCachedGzip',
> key: request.urlParsed.pathname
> }, function (onError) {
> local.zlib.gzip(options.result, function (error, data) {
> onError(error, !error && data.toString('base64'));
> });
> }, options.onNext);
> break;
> case 2:
> // set gzip header
> options.result = local.base64ToBuffer(data);
> response.setHeader('Content-Encoding', 'gzip');
> response.setHeader('Content-Length', options.result.length);
> options.onNext();
> break;
> case 3:
> local.middlewareCacheControlLastModified(request, response,
> options.onNext);
> break;
> case 4:
> response.end(options.result);
> break;
> }
> });
> options.modeNext = 0;
> options.onNext();
> };
>
> ...
>
> local.taskCreateCached = function (options, onTask, onError) {
> /*
>  * this function will
>  * 1. if 

Re: Re: Proposal: Allow Promise callbacks to be removed

2018-04-24 Thread Isiah Meadows
Here's a better idea: maybe `Promise.prototype.clear(promise)` and
`Promise.prototype.add(promise)` (with a parent reference to verify
its origin, of course). You can then manage "subscriptions" via just
tracking the returned chained promises if necessary. It's technically
blanket, but keep in mind resolve/reject callbacks aren't registered
uniquely like most event callback systems are.

-

Isiah Meadows
m...@isiahmeadows.com

Looking for web consulting? Or a new website?
Send me an email and we can get started.
www.isiahmeadows.com


On Tue, Apr 24, 2018 at 6:06 AM, Oliver Dunk  wrote:
> Based on feedback, I agree that a blanket `Promise.prototype.clear()` is a
> bad idea. I don’t think that is worth pursuing.
>
> I still think that there is value in this, especially the adding and
> removing of listeners you have reference to as Andrea’s PoC shows. Listeners
> would prevent the chaining issue or alternatively I think it would
> definitely be possible to decide on intuitive behaviour with the clear
> mechanic. The benefit of `clear(reference)` over listeners is that it adds
> less to the semantics.
>
> I think the proposed userland solutions are bigger than I would want for
> something that I believe should be available by default, but I respect that
> a lot of the people in this conversation are in a better position to make a
> judgement about that than me.
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Proposal: Allow Promise callbacks to be removed

2018-04-24 Thread Naveen Chawla
leads* to better predictability

On Tue, 24 Apr 2018, 4:44 pm Naveen Chawla,  wrote:

> Having promises be non-breakable I think is an advantage. I think it least
> to better predictability without having to check if another part of the
> code may have "broken" it. So I tend to prefer callbacks explicitly
> handling expiry in application logic, rather than allowing promises to be
> permanently broken in terms of their originally declared resolution
> behaviour. They are "promises" after all.
>
> On Tue, 24 Apr 2018 at 16:12 kai zhu  wrote:
>
>> I see a simple scenario like the following one:
>>
>>- user asks for a very expensive task clicking section A
>>- while it's waiting for it, user changes idea clicking section B
>>- both section A and section B needs that very expensive async call
>>- drop "going to section A" info and put "go to section B" to that
>>very same promise
>>- whenever resolved, do that action
>>
>> A caching mechanism to trigger only once such expensive operation would
>> also work, yet it's not possible to drop "go into A" and put "go into B”
>>
>>
>> for your scenario, what you want is a cacheable background-task, where
>> you can piggyback B onto the task initiated by A (e.g. common-but-expensive
>> database-queries that might take 10-60 seconds to execute).
>>
>> its generally more trouble than its worth to micromanage such tasks with
>> removeListeners or make them cancellable (maybe later on C wants to
>> piggyback, even tho A and B are no longer interested).  its easier
>> implementation-wise to have the background-task run its course and save it
>> to cache, and just have A ignore the results.  the logic is that because
>> this common-but-expensive task was recently called, it will likely be
>> called again in the near-future, so let it run  its course and cache the
>> result.
>>
>> here's a real-world cacheable-task implementation for such a scenario,
>> but it piggybacks the expensive gzipping of commonly-requested files,
>> instead of database-queries [1] [2]
>>
>> [1]
>> https://github.com/kaizhu256/node-utility2/blob/2018.1.13/lib.utility2.js#L4372
>> - piggyback gzipping of files onto a cacheable-task
>> [2]
>> https://github.com/kaizhu256/node-utility2/blob/2018.1.13/lib.utility2.js#L5872
>> - cacheable-task source-code
>>
>>
>>
>> ```js
>> /*jslint
>> bitwise: true,
>> browser: true,
>> maxerr: 4,
>> maxlen: 100,
>> node: true,
>> nomen: true,
>> regexp: true,
>> stupid: true
>> */
>>
>> local.middlewareAssetsCached = function (request, response,
>> nextMiddleware) {
>> /*
>>  * this function will run the middleware that will serve cached
>> gzipped-assets
>>  * 1. if cache-hit for the gzipped-asset, then immediately serve it to
>> response
>>  * 2. run background-task (if not already) to re-gzip the asset and
>> update cache
>>  * 3. save re-gzipped-asset to cache
>>  * 4. if cache-miss, then piggy-back onto the background-task
>>  */
>> var options;
>> options = {};
>> local.onNext(options, function (error, data) {
>> options.result = options.result ||
>> local.assetsDict[request.urlParsed.pathname];
>> if (options.result === undefined) {
>> nextMiddleware(error);
>> return;
>> }
>> switch (options.modeNext) {
>> case 1:
>> // skip gzip
>> if (response.headersSent ||
>>
>> !(/\bgzip\b/).test(request.headers['accept-encoding'])) {
>> options.modeNext += 1;
>> options.onNext();
>> return;
>> }
>> // gzip and cache result
>> local.taskCreateCached({
>> cacheDict: 'middlewareAssetsCachedGzip',
>> key: request.urlParsed.pathname
>> }, function (onError) {
>> local.zlib.gzip(options.result, function (error, data) {
>> onError(error, !error && data.toString('base64'));
>> });
>> }, options.onNext);
>> break;
>> case 2:
>> // set gzip header
>> options.result = local.base64ToBuffer(data);
>> response.setHeader('Content-Encoding', 'gzip');
>> response.setHeader('Content-Length', options.result.length);
>> options.onNext();
>> break;
>> case 3:
>> local.middlewareCacheControlLastModified(request, response,
>> options.onNext);
>> break;
>> case 4:
>> response.end(options.result);
>> break;
>> }
>> });
>> options.modeNext = 0;
>> options.onNext();
>> };
>>
>> ...
>>
>> local.taskCreateCached = function (options, onTask, onError) {
>> /*
>>  * this function will
>>  * 1. if cache-hit, then call onError with cacheValue
>>  * 2. run onTask in background to update cache
>>  * 3. save onTask's result to cache
>>  * 4. if 

Re: Proposal: Allow Promise callbacks to be removed

2018-04-24 Thread Naveen Chawla
Having promises be non-breakable I think is an advantage. I think it least
to better predictability without having to check if another part of the
code may have "broken" it. So I tend to prefer callbacks explicitly
handling expiry in application logic, rather than allowing promises to be
permanently broken in terms of their originally declared resolution
behaviour. They are "promises" after all.

On Tue, 24 Apr 2018 at 16:12 kai zhu  wrote:

> I see a simple scenario like the following one:
>
>- user asks for a very expensive task clicking section A
>- while it's waiting for it, user changes idea clicking section B
>- both section A and section B needs that very expensive async call
>- drop "going to section A" info and put "go to section B" to that
>very same promise
>- whenever resolved, do that action
>
> A caching mechanism to trigger only once such expensive operation would
> also work, yet it's not possible to drop "go into A" and put "go into B”
>
>
> for your scenario, what you want is a cacheable background-task, where you
> can piggyback B onto the task initiated by A (e.g. common-but-expensive
> database-queries that might take 10-60 seconds to execute).
>
> its generally more trouble than its worth to micromanage such tasks with
> removeListeners or make them cancellable (maybe later on C wants to
> piggyback, even tho A and B are no longer interested).  its easier
> implementation-wise to have the background-task run its course and save it
> to cache, and just have A ignore the results.  the logic is that because
> this common-but-expensive task was recently called, it will likely be
> called again in the near-future, so let it run  its course and cache the
> result.
>
> here's a real-world cacheable-task implementation for such a scenario, but
> it piggybacks the expensive gzipping of commonly-requested files, instead
> of database-queries [1] [2]
>
> [1]
> https://github.com/kaizhu256/node-utility2/blob/2018.1.13/lib.utility2.js#L4372
> - piggyback gzipping of files onto a cacheable-task
> [2]
> https://github.com/kaizhu256/node-utility2/blob/2018.1.13/lib.utility2.js#L5872
> - cacheable-task source-code
>
>
>
> ```js
> /*jslint
> bitwise: true,
> browser: true,
> maxerr: 4,
> maxlen: 100,
> node: true,
> nomen: true,
> regexp: true,
> stupid: true
> */
>
> local.middlewareAssetsCached = function (request, response,
> nextMiddleware) {
> /*
>  * this function will run the middleware that will serve cached
> gzipped-assets
>  * 1. if cache-hit for the gzipped-asset, then immediately serve it to
> response
>  * 2. run background-task (if not already) to re-gzip the asset and update
> cache
>  * 3. save re-gzipped-asset to cache
>  * 4. if cache-miss, then piggy-back onto the background-task
>  */
> var options;
> options = {};
> local.onNext(options, function (error, data) {
> options.result = options.result ||
> local.assetsDict[request.urlParsed.pathname];
> if (options.result === undefined) {
> nextMiddleware(error);
> return;
> }
> switch (options.modeNext) {
> case 1:
> // skip gzip
> if (response.headersSent ||
>
> !(/\bgzip\b/).test(request.headers['accept-encoding'])) {
> options.modeNext += 1;
> options.onNext();
> return;
> }
> // gzip and cache result
> local.taskCreateCached({
> cacheDict: 'middlewareAssetsCachedGzip',
> key: request.urlParsed.pathname
> }, function (onError) {
> local.zlib.gzip(options.result, function (error, data) {
> onError(error, !error && data.toString('base64'));
> });
> }, options.onNext);
> break;
> case 2:
> // set gzip header
> options.result = local.base64ToBuffer(data);
> response.setHeader('Content-Encoding', 'gzip');
> response.setHeader('Content-Length', options.result.length);
> options.onNext();
> break;
> case 3:
> local.middlewareCacheControlLastModified(request, response,
> options.onNext);
> break;
> case 4:
> response.end(options.result);
> break;
> }
> });
> options.modeNext = 0;
> options.onNext();
> };
>
> ...
>
> local.taskCreateCached = function (options, onTask, onError) {
> /*
>  * this function will
>  * 1. if cache-hit, then call onError with cacheValue
>  * 2. run onTask in background to update cache
>  * 3. save onTask's result to cache
>  * 4. if cache-miss, then call onError with onTask's result
>  */
> local.onNext(options, function (error, data) {
> switch (options.modeNext) {
> // 1. if cache-hit, then call onError with cacheValue
> case 1:
> // read 

Re: Proposal: Allow Promise callbacks to be removed

2018-04-24 Thread kai zhu
> I see a simple scenario like the following one:
> user asks for a very expensive task clicking section A
> while it's waiting for it, user changes idea clicking section B
> both section A and section B needs that very expensive async call
> drop "going to section A" info and put "go to section B" to that very same 
> promise
> whenever resolved, do that action
> A caching mechanism to trigger only once such expensive operation would also 
> work, yet it's not possible to drop "go into A" and put "go into B”

for your scenario, what you want is a cacheable background-task, where you can 
piggyback B onto the task initiated by A (e.g. common-but-expensive 
database-queries that might take 10-60 seconds to execute).

its generally more trouble than its worth to micromanage such tasks with 
removeListeners or make them cancellable (maybe later on C wants to piggyback, 
even tho A and B are no longer interested).  its easier implementation-wise to 
have the background-task run its course and save it to cache, and just have A 
ignore the results.  the logic is that because this common-but-expensive task 
was recently called, it will likely be called again in the near-future, so let 
it run  its course and cache the result.

here's a real-world cacheable-task implementation for such a scenario, but it 
piggybacks the expensive gzipping of commonly-requested files, instead of 
database-queries [1] [2]

[1] 
https://github.com/kaizhu256/node-utility2/blob/2018.1.13/lib.utility2.js#L4372 

 - piggyback gzipping of files onto a cacheable-task
[2] 
https://github.com/kaizhu256/node-utility2/blob/2018.1.13/lib.utility2.js#L5872 

 - cacheable-task source-code




```js
/*jslint
bitwise: true,
browser: true,
maxerr: 4,
maxlen: 100,
node: true,
nomen: true,
regexp: true,
stupid: true
*/

local.middlewareAssetsCached = function (request, response, nextMiddleware) {
/*
 * this function will run the middleware that will serve cached gzipped-assets
 * 1. if cache-hit for the gzipped-asset, then immediately serve it to response
 * 2. run background-task (if not already) to re-gzip the asset and update cache
 * 3. save re-gzipped-asset to cache
 * 4. if cache-miss, then piggy-back onto the background-task
 */
var options;
options = {};
local.onNext(options, function (error, data) {
options.result = options.result || 
local.assetsDict[request.urlParsed.pathname];
if (options.result === undefined) {
nextMiddleware(error);
return;
}
switch (options.modeNext) {
case 1:
// skip gzip
if (response.headersSent ||
!(/\bgzip\b/).test(request.headers['accept-encoding'])) {
options.modeNext += 1;
options.onNext();
return;
}
// gzip and cache result
local.taskCreateCached({
cacheDict: 'middlewareAssetsCachedGzip',
key: request.urlParsed.pathname
}, function (onError) {
local.zlib.gzip(options.result, function (error, data) {
onError(error, !error && data.toString('base64'));
});
}, options.onNext);
break;
case 2:
// set gzip header
options.result = local.base64ToBuffer(data);
response.setHeader('Content-Encoding', 'gzip');
response.setHeader('Content-Length', options.result.length);
options.onNext();
break;
case 3:
local.middlewareCacheControlLastModified(request, response, 
options.onNext);
break;
case 4:
response.end(options.result);
break;
}
});
options.modeNext = 0;
options.onNext();
};

...

local.taskCreateCached = function (options, onTask, onError) {
/*
 * this function will
 * 1. if cache-hit, then call onError with cacheValue
 * 2. run onTask in background to update cache
 * 3. save onTask's result to cache
 * 4. if cache-miss, then call onError with onTask's result
 */
local.onNext(options, function (error, data) {
switch (options.modeNext) {
// 1. if cache-hit, then call onError with cacheValue
case 1:
// read cacheValue from memory-cache
local.cacheDict[options.cacheDict] = 
local.cacheDict[options.cacheDict] ||
{};
options.cacheValue = 
local.cacheDict[options.cacheDict][options.key];
if (options.cacheValue) {
// call onError with cacheValue
options.modeCacheHit = true;
onError(null, JSON.parse(options.cacheValue));
if (!options.modeCacheUpdate) {
break;
}
  

Re: Proposal: Allow Promise callbacks to be removed

2018-04-24 Thread kai zhu
> I see a simple scenario like the following one:
> user asks for a very expensive task clicking section A
> while it's waiting for it, user changes idea clicking section B
> both section A and section B needs that very expensive async call
> drop "going to section A" info and put "go to section B" to that very same 
> promise
> whenever resolved, do that action
> A caching mechanism to trigger only once such expensive operation would also 
> work, yet it's not possible to drop "go into A" and put "go into B”

for your scenario, what you want is a cacheable background-task, where you can 
piggyback B onto the task initiated by A (e.g. common-but-expensive 
database-queries that might take 10-60 seconds to execute).

its generally more trouble than its worth to micromanage such tasks with 
removeListeners or make them cancellable (maybe later on C wants to piggyback, 
even tho A and B are no longer interested).  its easier implementation-wise to 
have the background-task run its course and save it to cache, and just have A 
ignore the results.  the logic is that because this common-but-expensive task 
was recently called, it will likely be called again in the near-future, so let 
it run  its course and cache the result.

here's a real-world cacheable-task implementation for such a scenario, but it 
piggybacks the expensive gzipping of commonly-requested files, instead of 
database-queries [1] [2]

[1] 
https://github.com/kaizhu256/node-utility2/blob/2018.1.13/lib.utility2.js#L4372 
- piggyback gzipping of files onto a cacheable-task
[2] 
https://github.com/kaizhu256/node-utility2/blob/2018.1.13/lib.utility2.js#L5872 
- cacheable-task source-code




```js
/*jslint
bitwise: true,
browser: true,
maxerr: 4,
maxlen: 100,
node: true,
nomen: true,
regexp: true,
stupid: true
*/

local.middlewareAssetsCached = function (request, response, nextMiddleware) {
/*
 * this function will run the middleware that will serve cached gzipped-assets
 * 1. if cache-hit for the gzipped-asset, then immediately serve it to response
 * 2. run background-task (if not already) to re-gzip the asset and update cache
 * 3. save re-gzipped-asset to cache
 * 4. if cache-miss, then piggy-back onto the background-task
 */
var options;
options = {};
local.onNext(options, function (error, data) {
options.result = options.result || 
local.assetsDict[request.urlParsed.pathname];
if (options.result === undefined) {
nextMiddleware(error);
return;
}
switch (options.modeNext) {
case 1:
// skip gzip
if (response.headersSent ||
!(/\bgzip\b/).test(request.headers['accept-encoding'])) {
options.modeNext += 1;
options.onNext();
return;
}
// gzip and cache result
local.taskCreateCached({
cacheDict: 'middlewareAssetsCachedGzip',
key: request.urlParsed.pathname
}, function (onError) {
local.zlib.gzip(options.result, function (error, data) {
onError(error, !error && data.toString('base64'));
});
}, options.onNext);
break;
case 2:
// set gzip header
options.result = local.base64ToBuffer(data);
response.setHeader('Content-Encoding', 'gzip');
response.setHeader('Content-Length', options.result.length);
options.onNext();
break;
case 3:
local.middlewareCacheControlLastModified(request, response, 
options.onNext);
break;
case 4:
response.end(options.result);
break;
}
});
options.modeNext = 0;
options.onNext();
};

...

local.taskCreateCached = function (options, onTask, onError) {
/*
 * this function will
 * 1. if cache-hit, then call onError with cacheValue
 * 2. run onTask in background to update cache
 * 3. save onTask's result to cache
 * 4. if cache-miss, then call onError with onTask's result
 */
local.onNext(options, function (error, data) {
switch (options.modeNext) {
// 1. if cache-hit, then call onError with cacheValue
case 1:
// read cacheValue from memory-cache
local.cacheDict[options.cacheDict] = 
local.cacheDict[options.cacheDict] ||
{};
options.cacheValue = 
local.cacheDict[options.cacheDict][options.key];
if (options.cacheValue) {
// call onError with cacheValue
options.modeCacheHit = true;
onError(null, JSON.parse(options.cacheValue));
if (!options.modeCacheUpdate) {
break;
}
}
// run background-task with lower priority for cache-hit
setTimeout(options.onNext, options.modeCacheHit && 
options.cacheTtl);
  

Re: Re: Proposal: Allow Promise callbacks to be removed

2018-04-24 Thread Oliver Dunk
Based on feedback, I agree that a blanket `Promise.prototype.clear()` is a bad 
idea. I don’t think that is worth pursuing.

I still think that there is value in this, especially the adding and removing 
of listeners you have reference to as Andrea’s PoC shows. Listeners would 
prevent the chaining issue or alternatively I think it would definitely be 
possible to decide on intuitive behaviour with the clear mechanic. The benefit 
of `clear(reference)` over listeners is that it adds less to the semantics.

I think the proposed userland solutions are bigger than I would want for 
something that I believe should be available by default, but I respect that a 
lot of the people in this conversation are in a better position to make a 
judgement about that than me.___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Proposal: Conditional `catch` in Promises

2018-04-24 Thread T.J. Crowder
For my part, if we're going to get into optional catching, I'd rather see a
common approach between promise `catch` and `try`/`catch`. There have been
various discussions about optional/filtered `catch` on the list ([here][1]
and [here][2], probably others).

Your approach is easily implemented in userland:

```js
const cif = (predicate, handler) => e => {
if (predicate(e)) {
return handler(e);
}
throw e;
};
```

then

```js
somePromise
.catch(cif(reason => reason instanceof ValidationError, reason =>
handleValidationError(reason))) // handle ValidationErrors
.catch(cif(reason => reason instanceof InternalError, reason =>
handleInternalError(reason))) // handle InternalErrors
.catch(cif(reason => handleOtherErrors(reason))); // catch all others
```

https://jsfiddle.net/maov8y0h/

To be clear, I'm not saying that just because something can be implemented
in userland, it shouldn't be considered. (Lots of things can be implemented
in userland.) But again, I'd want to see a cohesive approach, and I think
this probably doesn't take us in that direction.

-- T.J. Crowder

[1]: https://esdiscuss.org/topic/standardizing-conditional-try-catch
[2]: https://esdiscuss.org/topic/filtered-promise-catch

On Tue, Apr 24, 2018 at 10:35 AM, Ayush Gupta
 wrote:
> I propose that in `Promises`, we accept another function which returns a
> `boolean` as an argument to `catch`. It will enable us to write code like
> this:
>
> ```js
> return somePromise
> .catch((reason) => reason instanceof ValidationError, reason =>
> handleValidationError(reason)) // handle ValidationErrors
> .catch((reason) => reason instanceof InternalError, reason =>
> handleInternalError(reason)) // handle InternalErrors
> .catch(reason => handleOtherErrors(reason)) // catch all others
> ```
>
> If the passed function evaluates to `true`, call the actual rejection
> handler. If none of the catch are eligible to handle the rejection, it
> causes an unhandled rejection.
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Proposal: Conditional `catch` in Promises

2018-04-24 Thread Ayush Gupta
I propose that in `Promises`, we accept another function which returns a
`boolean` as an argument to `catch`. It will enable us to write code like
this:

```js
return somePromise
.catch((reason) => reason instanceof ValidationError, reason =>
handleValidationError(reason)) // handle ValidationErrors
.catch((reason) => reason instanceof InternalError, reason =>
handleInternalError(reason)) // handle InternalErrors
.catch(reason => handleOtherErrors(reason)) // catch all others
```

If the passed function evaluates to `true`, call the actual rejection
handler. If none of the catch are eligible to handle the rejection, it
causes an unhandled rejection.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Proposal: Allow Promise callbacks to be removed

2018-04-24 Thread Andrea Giammarchi
if the result is already known (resolved), Event Emitters are basically
useless though.

On Tue, Apr 24, 2018 at 11:13 AM, Ayush Gupta  wrote:

> In situations like this, I personally would use Event Emitters instead of
> promises.
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Proposal: Allow Promise callbacks to be removed

2018-04-24 Thread Ayush Gupta
In situations like this, I personally would use Event Emitters instead of
promises.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Proposal: Allow Promise callbacks to be removed

2018-04-24 Thread T.J. Crowder
On Mon, Apr 23, 2018 at 6:56 PM, Oliver Dunk
 wrote:
>
> My proposal is that we add a way of removing a particular
> callback, or all callbacks, from a Promise.

As has been raised, this gets complicated quickly when chains come into it.
Also, what if the same function has been used in more than one place in the
chain?

If the simple flag folks have mentioned isn't general enough, I wonder if
you'd be better off with a cancelable *callback*:

```js
function cancelableThen(f) {
const wrapper = value => f(value);
wrapper.cancel = () => {
f = value => value;
};
return wrapper;
}

// Using one:

function doSomething(value) {
// Do something with the value
return someResult;
}

const cb = cancelableThen(doSomething);
getAPromise().then(cb).catch(handleError);

// Later, you decide you don't need to `doSomething` anymore
cb.cancel();
```

https://jsfiddle.net/nt8tbfvk/1/ 

Simple userland solution. Additional Promise semantics seem like overkill...

-- T.J. Crowder
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Proposal: Allow Promise callbacks to be removed

2018-04-24 Thread Andrea Giammarchi
onto the actual then and catch, meaning if already resolved/rejected the
callback triggers right away ?

anyway, in case this proposal won't go anywhere, there is a module called
broadcast that would let you listen to named events, exposing a `drop`
functionality too.

Maybe that would be enough to move on with your code/needs.

Regards

On Mon, Apr 23, 2018 at 8:54 PM, Oliver Dunk  wrote:

> > What happens to `p2` if I "unthen" `f` from `p1`?
>
> That’s an interesting point to explore. I would intuitively say p2
> continues to exist, but is never resolved or rejected.
>
> > Interesting. I have a proof of concept that would let you do this
>
> Andrea, that’s pretty much exactly what I was thinking. I’m assuming there
> is no way to polyfill onto the actual .then and .catch methods?
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Proposal: Allow Promise callbacks to be removed

2018-04-24 Thread Naveen Chawla
How can you terminate an async call? All you're doing is refusing to handle
the result. Explain how I'm wrong if so.

On Tue, 24 Apr 2018 at 13:27 Andrea Giammarchi 
wrote:

> The `isStillValid` is limited in possibilities. I think listeners open
> new possibilities, specially for very complex operations.
>
> I see a simple scenario like the following one:
>
>- user asks for a very expensive task clicking section A
>- while it's waiting for it, user changes idea clicking section B
>- both section A and section B needs that very expensive async call
>- drop "going to section A" info and put "go to section B" to that
>very same promise
>- whenever resolved, do that action
>
> A caching mechanism to trigger only once such expensive operation would
> also work, yet it's not possible to drop "go into A" and put "go into B"
>
> My PoC also is per promise, so if you use `.then()` over the passed along
> promise, you can add your own listeners in there too, without affecting the
> initial one (and vice versa)
>
>
>
>
> On Mon, Apr 23, 2018 at 11:07 PM, Alex Vincent 
> wrote:
>
>>
>> My proposal is that we add a way of removing a particular callback, or
>>> all callbacks, from a Promise. This is different to cancelling a Promise
>>> and would instead happen if you want the operation to continue but are no
>>> longer interested in running a function when the Promise is resolved or
>>> rejected.
>>>
>>
>> Devil's advocate from the peanut gallery:  what's so hard about adding:
>>
>> ```javascript
>> if (!isStillValid) return;
>> ```
>> --
>> "The first step in confirming there is a bug in someone else's work is
>> confirming there are no bugs in your own."
>> -- Alexander J. Vincent, June 30, 2001
>>
>> ___
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Proposal: Allow Promise callbacks to be removed

2018-04-24 Thread Andrea Giammarchi
The `isStillValid` is limited in possibilities. I think listeners open new
possibilities, specially for very complex operations.

I see a simple scenario like the following one:

   - user asks for a very expensive task clicking section A
   - while it's waiting for it, user changes idea clicking section B
   - both section A and section B needs that very expensive async call
   - drop "going to section A" info and put "go to section B" to that very
   same promise
   - whenever resolved, do that action

A caching mechanism to trigger only once such expensive operation would
also work, yet it's not possible to drop "go into A" and put "go into B"

My PoC also is per promise, so if you use `.then()` over the passed along
promise, you can add your own listeners in there too, without affecting the
initial one (and vice versa)




On Mon, Apr 23, 2018 at 11:07 PM, Alex Vincent  wrote:

>
> My proposal is that we add a way of removing a particular callback, or all
>> callbacks, from a Promise. This is different to cancelling a Promise and
>> would instead happen if you want the operation to continue but are no
>> longer interested in running a function when the Promise is resolved or
>> rejected.
>>
>
> Devil's advocate from the peanut gallery:  what's so hard about adding:
>
> ```javascript
> if (!isStillValid) return;
> ```
> --
> "The first step in confirming there is a bug in someone else's work is
> confirming there are no bugs in your own."
> -- Alexander J. Vincent, June 30, 2001
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss