What is JavaScript equivalent to Ruby's Array#pact?
Long version.... I followed the examples at blog.nemikor. His last example closes out old requests, but then pendings
continues to be filled with obsolete requests. This looks like a memory leak to me.
My solution is to iterate over pendings
with filter
as below, but this seems like there may be a race condition between pendings.push
and pendings = pendings.filter
. Am I being paranoid? If a race condition exists, how should I fix it?
var pendings = [];
// there is a route
app.get('/some/path', function (request, response) {
pendings.push({
response: response,
requestedAt: new Date().getTime()
});
});
setInterval(function () {
var expiration = new Date().getTime() - (1000 * 30);
pendings = pendings.filter(function (pending, index) {
if (pending.requestedAt > expiration) {
return true;
} else {
pending.response.writeHead(408, { 'Content-Type': 'text/plain' });
pending.response.end('');
}
});
}, 1000);
What is JavaScript equivalent to Ruby's Array#pact?
Long version.... I followed the examples at blog.nemikor.. His last example closes out old requests, but then pendings
continues to be filled with obsolete requests. This looks like a memory leak to me.
My solution is to iterate over pendings
with filter
as below, but this seems like there may be a race condition between pendings.push
and pendings = pendings.filter
. Am I being paranoid? If a race condition exists, how should I fix it?
var pendings = [];
// there is a route
app.get('/some/path', function (request, response) {
pendings.push({
response: response,
requestedAt: new Date().getTime()
});
});
setInterval(function () {
var expiration = new Date().getTime() - (1000 * 30);
pendings = pendings.filter(function (pending, index) {
if (pending.requestedAt > expiration) {
return true;
} else {
pending.response.writeHead(408, { 'Content-Type': 'text/plain' });
pending.response.end('');
}
});
}, 1000);
Share
Improve this question
asked May 30, 2011 at 23:20
ravinggeniusravinggenius
8681 gold badge6 silver badges15 bronze badges
3
- 1 pact-like behavior – Zabba Commented May 30, 2011 at 23:24
- MDC doco on filter if you need it. – RobG Commented May 31, 2011 at 0:36
- Follow Zabba's link for an answer to the title question... – AShelly Commented Nov 19, 2012 at 16:16
4 Answers
Reset to default 3An old thread but it deserves an answer to the original question:
What is JavaScript equivalent to Ruby's Array#pact?
list1 = [null, 'no', 'nulls', null]
// With plain JS
jsFilter = list1.filter(function (obj) { return obj })
// With ES6
let filtered = list1.filter((obj) => obj)
//> (2) ["no", "nulls"]
console.log(es6Filter)
But there is a caveat, because:
filter() calls a provided callback function once for each element in an array and constructs a new array of all the values for which callback returns a value that coerces to true.
falsey = [false, 0, 0n, '', NaN, null, undefined]
truthy = [true, 1, ' ']
list2 = ['returns', 'only', 'truthy', 'values'].concat(truthy).concat(falsey)
let filtered = list2.filter((obj) => obj)
//> (7) ["returns", "only", "truthy", "values", true, 1, " "]
console.log(filtered)
In order to have it working like Ruby's pact, you can do:
falsey = [false, 0, 0n, '', NaN, null, undefined]
truthy = [true, 1, ' ']
list3 = ['works', 'like', "Ruby's", 'pact'].concat(truthy).concat(falsey)
let them_go = [null, undefined] // Just a fun with variable names
let filtered = list3.filter((obj) => { return !them_go.includes(obj) })
//> (12) ["works", "like", "Ruby's", "pact", true, 1, " ", false, 0, 0n, "", NaN]
console.log(filtered)
If you want to remove all the empty elements (empty Strings, Arrays, and Objects) from an array, you can check my answer here -> https://stackoverflow./a/59905255/3251051
References:
- https://ruby-doc/core-2.6.5/Array.html#method-i-pact
- https://developer.mozilla/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
- https://developer.mozilla/en-US/docs/Glossary/Falsy
- https://developer.mozilla/en-US/docs/Glossary/Truthy
- http://kenglish.co/blog/2018/1/remove-null-elements-from-array-with-javascript
You have no threads in JavaScript, so there can be no race condition. All code is sequenced and will transfer control only after it's done running. So your interval function will run till pletion before any other function is going to touch pendings
.
This holds for things like setTimeout
and setInterval
.
As an experiment: If you made a timeout using setTimeout
to fire after 1 second. And after that you write a while-loop that blocks for 2 seconds, your timeout will fire after that, so much longer than 1 second.
Something crude:
var timer = setTimeout(function () {
alert("hi!");
}, 1000);
var now = new Date();
var till = new Date(now + 2);
while(new Date() < till) {} // block for 2 seconds
You may want to take a look at the Underscore.js library
http://documentcloud.github./underscore/
This provides many useful low-level functions to deal with collections, arrays and objects. It includes both a pact
function (though I think it serves a different purpose to what you're looking for) and a filter
function.
As long as you're not doing I/O, i.e., you are only doing in-memory operations, you are guaranteed to not be interrupted (due to the nature of the event loop).
Being so, be careful, if your collection is too long (like on the thousands or more), because you can block the event loop for some time, not letting the other requests be serviced.