
Research
Security News
The Landscape of Malicious Open Source Packages: 2025 Mid‑Year Threat Report
A look at the top trends in how threat actors are weaponizing open source packages to deliver malware and persist across the software supply chain.
nThen is designed to be the most small, simple and intuitive asynchronous library.
let x = synchronous_call();
let y = use(x);
let a = another_sync_call(x); // Hey!
let b = yet_another_sync_call(x); // these two could run at the same time!
let z = something_else_synchronous(b);
let c = last_synchronous_call(z);
do_next_job(c);
Ok so we learned that doing it that way is slow and we have asynchronous so we never have to be slow anymore.
asyncCall(function (x) {
let y = use(x);
let aa;
let cc;
anotherCall(x, function (a) {
aa = a;
if (cc) { doNextJob(cc); }
});
yetAnotherCall(x, function (b) {
somethingElse(b, function (z) {
lastCall(z, function (c) {
cc = c;
if (aa) { doSomethingElse(aa); }
});
});
});
});
That doesn't look like very much fun :( And to make matters worse, what happens if one of those functions never returns?
var to = setTimeout(function() { stopEverything(); }, 3000);
You can see where this is going.
nThen allows you to do things in parallel by putting them in blocks and one block will not execute until all of the callbacks from the previous one have completed.
How do we know when all callbacks have been completed ? You wrap them using the waitFor function wrapper. Waitfor wraps a function, so the result of waitFor is another function and when that is called, all arguments are passed through to the function which was given to waitFor, however, nThen will block until all waitFors have been called.
You can use waitFor as many times as you want in an nThen block, you can even use a waitFor invocation inside of another waitFor invocation and it will keep the nThen block from terminating.
For example this works:
const nThen = require('nthen');
const Fs = require('fs');
nThen(function (waitFor) {
Fs.readdir('/dev', waitFor(function (err, array) {
if (err) { throw err; }
if (array.indexOf('random') > -1) {
Fs.stat('/dev/random', waitFor(function (err, stat) {
if (err) { throw err; }
console.log(stat);
}));
}
}));
}).nThen(function (waitFor) {
console.log('completed');
});
Sometimes you want to do a variable number of things in sequence. Suppose you wanted to stat every file in the /dev directory but you want to do them one at a time.
You can loop over all files using nThen to access each one sequencially like this:
const nThen = require('./index.js');
const Fs = require('fs');
var nt = nThen;
Fs.readdir('/dev', function (err, array) {
if (err) { throw err; }
array.forEach(function (x) {
nt = nt(function (waitFor) {
Fs.stat('/dev/' + x, waitFor(function (err, stat) {
if (err) { throw err; }
console.log(stat);
}));
}).nThen;
});
nt(function (waitFor) {
console.log('done');
});
});
You can use multiple levels of nesting of nThen, for example you might use a loop of async operations inside of one block of larger nThen chain, like this. Notice waitFor can be used without a wrapped function.
const nThen = require('./index.js');
const Fs = require('fs');
let fileList;
nThen(function (waitFor) {
Fs.readdir('/dev', waitFor(function (err, array) {
if (err) { throw err; }
fileList = array;
}));
}).nThen(function (waitFor) {
let nt = nThen;
fileList.forEach(function (x) {
nt = nt(function (waitFor) {
Fs.stat('/dev/' + x, waitFor(function (err, stat) {
if (err) { throw err; }
console.log(stat);
}));
}).nThen;
});
// This line is what will hold open this nThen block until
// all of the files in fileList have been stated.
nt(waitFor());
}).nThen(function (waitFor) {
console.log('done');
});
You can end your nThen chain with an orTimeout call which will abort the execution of the nThen chain if the execution takes more than a given number of milliseconds.
const nThen = require('./index.js');
nThen(function (waitFor) {
let done = waitFor(function () { console.log('this never gets invoked'); });
if (1 === 2) {
// never happens
done();
}
}).nThen(function (waitFor) {
console.log('so we never get to this point');
}).orTimeout(function () {
console.log('timed out after 1 second');
}, 1000);
Public Domain or MIT license, as you wish.
FAQs
Simple intuitive asynchronous control flow.
The npm package nthen receives a total of 269 weekly downloads. As such, nthen popularity was classified as not popular.
We found that nthen demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
A look at the top trends in how threat actors are weaponizing open source packages to deliver malware and persist across the software supply chain.
Security News
ESLint now supports HTML linting with 48 new rules, expanding its language plugin system to cover more of the modern web development stack.
Security News
CISA is discontinuing official RSS support for KEV and cybersecurity alerts, shifting updates to email and social media, disrupting automation workflows.