Let's say I have this code, and I have written a function called handleSmell()
in a package that others can use:
const streamSomeUrl = (url='https://salmon.net/river') => {
console.info('...connecting...');
const { data, headers } = await axios({
url,
method: 'GET',
responseType: 'stream',
});
return new Promise((resolve, reject) => {
data.on('data', (chunk) => {
if(smellsFunny(chunk)) {
// promise aware function
handleSmell(chunk) // <--- behaves differently inside a promise.
// E.g. prints "Smell inside a promise"
}
});
})
}
Is there a way, that the function handleSmell
to tell if it's in a promise or not? By that I mean, it would behave differently to here:
readFile('/etc/fish', (err, data) => {
if(smellsFunny(data)) {
// promise aware function
handleSmell(data) // <--- behaves differently inside a promise.
// E.g. prints "Smell *not* inside a promise"
...
}
});
I'm trying to figure out if I can do with without taking reject/resolve callbacks in to the handleSmell
function (and then if missing, know I'm not in a promise).
As far as I'm aware I can't use the fact that different data is passed through, both chunk
and data
are strings/buffers?
Is this at all possible? I'm motivated by this question, mainly this bit from an answer:
Any time you are inside of a promise callback, you can use throw. However, if you're in any other asynchronous callback, you must use reject.
new Promise(function() {
setTimeout(function() {
throw 'or nah';
// return Promise.reject('or nah'); also won't work
}, 1000);
}).catch(function(e) {
console.log(e); // doesn't happen
});
My preference is to throw, but I want to know if I call a reject callback (i.e. from the parent reject) it will work:
function handleSmell(suspectData, reject=False) {
const inPromise = //?????
if (inPromise && reject) {
return reject('SMELLY REJECT!')
} else if (inPromise) {
throw new Error('SMELLY THROWN!')
} else { console.error('SMELLY NON-PROMISE!') }
}
// Both these should work
new Promise(function() {
setTimeout(function() {
handleSmell('cheese');
}).catch(function(e) {
console.log(e); // doesn't try to throw
});
new Promise(function(resolve, reject) {
setTimeout(function() {
handleSmell('cheese', reject);
}, 1000);
}).catch(function(e) {
console.log(e); // this works
});
The alternative is promisifying the non-promise (as per link).
But can I avoid that if possible?