What's the proper way to chain something when you need to append the results to an array that is sitting at the top level of a function's scope?
function run() {
let array = []
let input = 'object'
promiseA(input)
.then((result) => {
array.push(result)
})
promiseB(input)
.then((result) => {
array.push(result)
})
console.log(array.join(' '))
}
Order doesn't matter for my application, I can parallelize it if that's considered best practices. It's literally just checking for a condition, there's no async calls to get results from an API or anything like that.
You should use Promise.all to wait for promise A and promise B to complete. Promise.all will receive an array of results (from each Promise) that you can then use.
You might have something like:
var promiseA = doSomethingThatReturnsPromise(input);
var promiseB = doSomethingThatReturnsPromise(anotherInput);
Promise.all([promiseA, promiseB]).then(function(resultsArray) { // do something });
your function will look like this
function run () {
return Promise.all([promiseA(), promiseB()]).then(([resultA, resultB])=>{ })
}
An alternative is using async function:
This approach executes the promises one by one, that way you will be able to handle the result with the desired execution order.
function promiseA(input) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve(input);
}, 1000);
});
}
function promiseB(input) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve(input);
}, 500);
});
}
async function run() {
let array = [];
let input = 'Ele';
array.push(await promiseA(input));
input = "from SO";
array.push(await promiseB(input));
console.log(array.join(' '))
}
console.log('Wait for 1.5sec...')
run()
Answering the Question Asked
This is the correct way to sequence or chain Promises:
one(arr).then(two).then(log, fail);
This directly answers the question without offering other possible solutions.
Please note there are no side effects. The "scope" issue mentioned in the comments is absolutely avoided.
The sample snippet implements this:
let arr = [];
function one(arr) {
return new Promise((res, rej) => {
arr.push('one');
res(arr);
});
}
function two(arr) {
return new Promise((res, rej) => {
arr.push('two');
res(arr);
});
}
function log(arr){
console.log(arr);
}
function fail(reason){
console.log(reason);
}
one(arr).then(two).then(log, fail);
Related
I have a recursive function which is returning promise, there is some conditions which on fulfillment the resolve will fire. But the resolve always returns undefined.
Here is the code:
var children = [];
var temp = [];
function getRelationsOfRep(repId) {
var index;
return new Promise(function (resolve, reject) {
return RepRelation.findOne({_id: repId}).then(function (repData) {
if (<condition>) {
temp = temp.concat(repData.children);
temp.forEach(function (childId) {
return getRelationsOfRep(childId);
});
} else {
// else
}
if (<another condition>) {
return resolve(children);
}
}).catch(function (error) {
return reject(error);
})
})
}
function updateRepData(id){
children = [];
temp = [];
getRelationsOfRep(id).then(function (branchesData) {
console.log('branchesData:: ', branchesData); // it prints undefined
})
}
I'm trying to get all children of a Representative and the children of its children (if any) and return them all.
What is it that I'm doing wrong?
Any help would be much appreciated.
Thanks in advance.
Use Promise.all() to capture all the promises in Loop.
Instead of:
temp.forEach(function (childId) {
return getRelationsOfRep(childId);
});
Try:
var promisesArray = [];
temp.forEach(function (childId) {
promisesArray.push(getRelationsOfRep(childId));
});
return Promise.all(promisesArray);
Using something like this, you will be able to get nested response for the recursive calls.
P.S. Not tested, modify according to the logic you want.
You are making things slightly complicated. I think what you want to achieve is to use promise to return a result from a recursive function.
Here's a cleaner version
A cleaner solution -
getRelationsOfRep(repId) {
return new Promise( function(resolve,reject) {
recursiveFunctionCall(repId);
function recursiveFunctionCall(repId) {
//your recursive function logic
recursiveFunctionCall(childId);
if(...) //edge case condition
resolve('your-answer');
else
reject('your-error')
}
});
This way, you'll just be using one promise and returning when your recursive function resolves.
Sometimes code would like to know if a particular function (or children) are running or not. For instance, node.js has domains which works for async stuff as well (not sure if this includes async functions).
Some simple code to explain what I need would by like this:
inUpdate = true;
try {
doUpdate();
} finally {
inUpdate = false;
}
This could then be used something like:
function modifyThings() {
if (inUpdate) throw new Error("Can't modify while updating");
}
With the advent of async this code breaks if the doUpdate() function is asynchronous. This was of course already true using callback-style functions.
The doUpdate function could of course be patched to maintain the variable around every await, but even if you have control over the code, this is cumbersome and error prone and this breaks when trying to track async function calls inside doUpdate.
I tried monkey-patching Promise.prototype:
const origThen = Promise.prototype.then;
Promise.prototype.then = function(resolve, reject) {
const isInUpdate = inUpdate;
origThen.call(this, function myResolve(value) {
inUpdate = isInUpdate;
try {
return resolve(value);
} finally {
inUpdate = false;
}
}, reject);
}
Unfortunately this doesn't work. I'm not sure why, but the async continuation code ends up running outside of the resolve call stack (probably using a microtask).
Note that it's not enough to simply do:
function runUpdate(doUpdate) {
inUpdate = true;
doUpdate.then(() => inUpdate = false).catch(() => inUpdate = false);
}
The reason is:
runUpdate(longAsyncFunction);
console.log(inUpdate); // incorrectly returns true
Is there any way to track something from outside an async function so it's possible to tell if the function called, or any of its descendant calls are running?
I know that it's possible to simulate async functions with generators and yield, in which case we have control over the call stack (since we can call gen.next()) but this is a kludge which the advent of async functions just got around to solving, so I'm specifically looking for a solution that works with native (not Babel-generated) async functions.
Edit: To clarify the question: Is there's a way for outside code to know if a particular invocation of an async function is running or if it is suspended, assuming that this code is the caller of the async function. Whether it's running or not would be determined by a function that ultimately is called by the async function (somewhere in the stack).
Edit: To clarify some more: The intended functionality would be the same as domains in node.js, but also for the browser. Domains already work with Promises, so async functions probably work as well (not tested).
This code allows me to do what I want to a certain extent:
function installAsyncTrack() {
/* global Promise: true */
if (Promise.isAsyncTracker) throw new Error('Only one tracker can be installed');
const RootPromise = Promise.isAsyncTracker ? Promise.rootPromise : Promise;
let active = true;
const tracker = {
track(f, o, ...args) {
const prevObj = tracker.trackObj;
tracker.trackObj = o;
try {
return f.apply(this, args);
} finally {
tracker.trackObj = prevObj;
}
},
trackObj: undefined,
uninstall() {
active = false;
if (Promise === AsyncTrackPromise.prevPromise) return;
if (Promise !== AsyncTrackPromise) return;
Promise = AsyncTrackPromise.prevPromise;
}
};
AsyncTrackPromise.prototype = Object.create(Promise);
AsyncTrackPromise.rootPromise = RootPromise;
AsyncTrackPromise.prevPromise = Promise;
Promise = AsyncTrackPromise;
AsyncTrackPromise.resolve = value => {
return new AsyncTrackPromise(resolve => resolve(value));
};
AsyncTrackPromise.reject = val => {
return new AsyncTrackPromise((resolve, reject) => reject(value));
};
AsyncTrackPromise.all = iterable => {
const promises = Array.from(iterable);
if (!promises.length) return AsyncTrackPromise.resolve();
return new AsyncTrackPromise((resolve, reject) => {
let rejected = false;
let results = new Array(promises.length);
let done = 0;
const allPromises = promises.map(promise => {
if (promise && typeof promise.then === 'function') {
return promise;
}
return new AsyncTrackPromise.resolve(promise);
});
allPromises.forEach((promise, ix) => {
promise.then(value => {
if (rejected) return;
results[ix] = value;
done++;
if (done === results.length) {
resolve(results);
}
}, reason => {
if (rejected) return;
rejected = true;
reject(reason);
});
});
});
};
AsyncTrackPromise.race = iterable => {
const promises = Array.from(iterable);
if (!promises.length) return new AsyncTrackPromise(() => {});
return new AsyncTrackPromise((resolve, reject) => {
let resolved = false;
if (promises.some(promise => {
if (!promise || typeof promise.then !== 'function') {
resolve(promise);
return true;
}
})) return;
promises.forEach((promise, ix) => {
promise.then(value => {
if (resolved) return;
resolved = true;
resolve(value);
}, reason => {
if (resolved) return;
resolved = true;
reject(reason);
});
});
});
};
function AsyncTrackPromise(handler) {
const promise = new RootPromise(handler);
promise.trackObj = tracker.trackObj;
promise.origThen = promise.then;
promise.then = thenOverride;
promise.origCatch = promise.catch;
promise.catch = catchOverride;
if (promise.finally) {
promise.origFinally = promise.finally;
promise.finally = finallyOverride;
}
return promise;
}
AsyncTrackPromise.isAsyncTracker = true;
function thenOverride(resolve, reject) {
const trackObj = this.trackObj;
if (!active || trackObj === undefined) return this.origThen.apply(this, arguments);
return this.origThen.call(
this,
myResolver(trackObj, resolve),
reject && myResolver(trackObj, reject)
);
}
function catchOverride(reject) {
const trackObj = this.trackObj;
if (!active || trackObj === undefined) return this.origCatch.catch.apply(this, arguments);
return this.origCatch.call(
this,
myResolver(trackObj, reject)
);
}
function finallyOverride(callback) {
const trackObj = this.trackObj;
if (!active || trackObj === undefined) return this.origCatch.catch.apply(this, arguments);
return this.origCatch.call(
this,
myResolver(trackObj, reject)
);
}
return tracker;
function myResolver(trackObj, resolve) {
return function myResolve(val) {
if (trackObj === undefined) {
return resolve(val);
}
RootPromise.resolve().then(() => {
const prevObj = tracker.trackObj;
tracker.trackObj = trackObj;
RootPromise.resolve().then(() => {
tracker.trackObj = prevObj;
});
});
const prevObj = tracker.trackObj;
tracker.trackObj = trackObj;
try {
return resolve(val);
} finally {
tracker.trackObj = prevObj;
}
};
}
}
tracker = installAsyncTrack();
function track(func, value, ...args) {
return tracker.track(func, { value }, value, ...args);
}
function show(where, which) {
console.log('At call', where, 'from', which, 'the value is: ', tracker.trackObj && tracker.trackObj.value);
}
async function test(which, sub) {
show(1, which);
await delay(Math.random() * 100);
show(2, which);
if (sub === 'resolve') {
await Promise.resolve(test('sub'));
show(3, which);
}
if (sub === 'call') {
await test(which + ' sub');
show(3, which);
}
}
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
track(test, 'test1');
track(test, 'test2');
track(test, 'test3', 'resolve');
track(test, 'test4', 'call');
It replaces the native Promise with my own. This promise stores the current context (taskObj) on the promise.
When the .then callback or its ilk are called, it does the following:
It creates a new native promise that immediately resolves. This adds a new microtask to the queue (according to spec, so should be reliable).
It calls the original resolve or reject. At least in Chrome and Firefox, this generates another microtask onto the queue that will run next part of the async function. Not sure what the spec has to say about this yet. It also restores the context around the call so that if it's not await that uses it, no microtask gets added here.
The first microtask gets executed, which is my first (native) promise being resolved. This code restores the current context (taskObj). It also creates a new resolved promise that queues another microtask
The second microtask (if any) gets executed, running the JS in the async function to until it hits the next await or returns.
The microtask queued by the first microtask gets executed, which restores the context to what it was before the Promise resolved/rejected (should always be undefined, unless set outside a tracker.track(...) call).
If the intercepted promise is not native (e.g. bluebird), it still works because it restores the state during the resolve(...) (and ilk) call.
There's one situation which I can't seem to find a solution for:
tracker.track(async () => {
console.log(tracker.taskObj); // 'test'
await (async () => {})(); //This breaks because the promise generated is native
console.log(tracker.taskObj); // undefined
}, 'test')
A workaround is to wrap the promise in Promise.resolve():
tracker.track(async () => {
console.log(tracker.taskObj); // 'test'
await Promise.resolve((async () => {})());
console.log(tracker.taskObj); // undefined
}, 'test')
Obviously, a lot of testing for all the different environments is needed and the fact that a workaround for sub-calls is needed is painful. Also, all Promises used need to either be wrapped in Promise.resolve() or use the global Promise.
[is it] possible to tell if the function called, or any of its descendant calls are running?
Yes. The answer is always no. Cause there is only one piece of code running at a time. Javascript is single threaded per definition.
Don't make it any more complicated than it needs to be. If doUpdate returns a promise (like when it is an async function), just wait for that:
inUpdate = true;
try {
await doUpdate();
//^^^^^
} finally {
inUpdate = false;
}
You can also use the finally Promise method:
var inUpdate = true;
doUpdate().finally(() => {
inUpdate = false;
});
That'll do just like like your synchronous code, having inUpdate == true while the function call or any of its descendants are running. Of course that only works if the asynchronous function doesn't settle the promise before it is finished doing its thing. And if you feel like the inUpdate flag should only be set during some specific parts of the doUpdate function, then yes the function will need to maintain the flag itself - just like it is the case with synchronous code.
I am listening to user events and some of these depend on the completion of others. Dealing with these events is an asynchronous task, so I use promises.
Let's say I've got this:
A
-> B
-> C
-> ...
-> D
-> E
-> ...
-> F
My initial approach was to save a promise for A and attach the handling of B using the then method of A's promise. The same for B and C ... D and D and E ... F.
But these events can happen almost in the same time, and B can happen before A. Since I cannot listen to a promise that not exists yet... How would you resolve this?
My idea is to define an object for each level (A, B, D), where I can attach a promise and the handling of future events. When attaching a promise, I would iterate the handling of future events and set them to the promise's then. When attaching a future event, I would look if there is a promise, and attach that to it's then or save that into an array or something.
Do you know an existing solution that already solves this issue or shall I follow with my idea?
Thank you.
Further clarification as requested:
I'm listening to multimedia events in the client side that are forwarded via websocket (using socket.io) to the server. The order of the events is indeed first A, then B, etc. But since some of them happen almost at the same time, they can be processed out of order.
Example code
let promiseForA, promiseForB;
socket.on('A', data => {
promiseForA = asynchronousTaskForA();
});
socket.on('B', data => {
// What if promiseForA has not yet been defined?
promiseForA.then(neededValue => {
asynchronousTaskForB(neededValue);
});
});
socket.on('C', data => {
// What if promiseForB has not yet been defined?
promiseForB.then(neededValue => {
asynchronousTaskForC(neededValue);
});
});
socket.on('D', data => {
// What if promiseForB has not yet been defined?
promiseForB.then(neededValue => {
asynchronousTaskForD(neededValue);
});
});
function asynchronousTaskForA() {
// something
resolve('something needed by B');
}
function asynchronousTaskForB(value) {
// something with value
resolve('something needed by C ... D');
}
function asynchronousTaskForC(value) {
// something with value
resolve();
}
function asynchronousTaskForD(value) {
// something with value
resolve('something needed by E ... F');
}
My idea
So... it works. It may be an anti-pattern, wrong or insane, but... I'd like to know of a better alternative.
let PromiseWaiter = function() {
let promise = null;
let thens = [];
let self = this;
this.setPromise = function (p) {
promise = p;
thens.forEach(t => {
p.then(t);
});
};
this.then = function(t) {
if (promise === null) {
thens.push(t);
} else {
promise.then(t);
}
return self;
};
this.reset = function() {
promise = null;
thens = [];
};
};
module.exports = PromiseWaiter;
Using it:
let waitForA = new PromiseWaiter();
let waitForB = new PromiseWaiter();
let waitForD = new PromiseWaiter();
socket.on('A', data => {
waitForA.setPromise(asynchronousTaskForA());
});
socket.on('B', data => {
waitForA.then(neededValue => {
waitForB.setPromise(asynchronousTaskForB(neededValue));
});
});
socket.on('C', data => {
waitForB.then(neededValue => {
asynchronousTaskForC(neededValue);
});
});
socket.on('D', data => {
waitForB.then(neededValue => {
waitForD.setPromise(asynchronousTaskForD(neededValue));
});
});
// Note: I am confused why these functions did not return a Promise before
// They have always done that.
function asynchronousTaskForA() {
return new Promise((resolve, reject) => {
// something
resolve('something needed by B');
});
}
function asynchronousTaskForB(value) {
return new Promise((resolve, reject) => {
// something with value
resolve('something needed by C ... D');
});
}
function asynchronousTaskForC(value) {
return new Promise((resolve, reject) => {
// something with value
resolve();
});
}
function asynchronousTaskForD(value) {
return new Promise((resolve, reject) => {
// something with value
resolve('something needed by E ... F');
});
}
Thank you!
What if promiseForA has not yet been defined?
Just don't assign to it asynchronously. Create it immediately - make a promise for it. Oh, a promise for a promise is just a promise.
const A = new Promise(resolve => socket.on('A', resolve));
const B = new Promise(resolve => socket.on('B', resolve));
const C = new Promise(resolve => socket.on('C', resolve));
const D = new Promise(resolve => socket.on('D', resolve));
const afterA = A.then(asynchronousTaskForA);
const afterB = Promise.all([afterA, B]).then(asynchronousTaskForB);
const afterC = Promise.all([afterB, C]).then(asynchronousTaskForC);
const afterD = Promise.all([afterB, D]).then(asynchronousTaskForD);
My idea may be an anti-pattern, wrong or insane, but... it works.
Yeah. The problems I see with it is that it looks very much like a promise (or deferred), but isn't one:
setPromise is just resolve
then does register callbacks, but doesn't return a promise that waits for the callback result, so is not chainable
reset is not possible with promises1, but I'm not sure whether you really need this.
As I said in the comments, better don't roll your own solution but just use Promise. Of course you might write a helper function socket.getPromiseForNext('A') or so.
1: You can however use an implementation like Creed that supports cancellation. I suspect just creating a new instance that waits for the next event should suffice though.
You can create a promise in the return statement of then callback.
Example:
promiseA
.then( data => {
return new Promise((resolve, reject) => {
// do some job
});
})
As far as you are using node, you can use async/await approach:
async function startFlow() {
// here you sure create promise, instead of promise A
const res1 = await promiseA;
// here you sure create promise, instead of promise B
const res2 = await promiseB;
// etc...
}
// Start your functions execution
startFlow();
I have a working promise chain:
function startSync(db) {
var promise = new Promise(function(resolve, reject) {
syncCats(db)
.then(syncTrees(db))
.then(syncCars(db))
...
.then(resolve());
});
return promise;
}
This works great. It performs each of those function calls, waiting for each one to complete before firing off another. Each of those functions returns a promise, like so:
function syncCaesar(db) {
var promise = new Promise(resolve, reject) {
// do aysnc db calls, and whatnot, resolving/rejecting appropriately
}
return promise;
}
I need to run this chain on a series of databases, sequentially.
I've tried other solutions here, but they would fire off syncCats() all at once.
For instance:
var promise = Promise.resolve();
dbs.forEach(function(db) {
promise = promise.then(startSync(db));
}
Fires off syncCats(db[0]) and syncCats(db[1]) simultaneously.
Edit:
Performing startSync(dbs[0]).then(startSync(dbs[1])); acts the same.
Edit2: Also performs the same:
dbs.forEach(function(db) {
promise = promise.then(function() {
return startSync(db);
}
}
You're calling startSync and then passing its return value in to then. So naturally, if you do that twice, it's going to start the process twice in parallel.
Instead, pass in a function that doesn't call startSync until it's called:
var promise = Promise.resolve();
dbs.forEach(function(db) {
promise = promise.then(function() { startSync(db); });
});
or with ES2015:
let promise = Promise.resolve();
dbs.forEach(function(db) {
promise = promise.then(_ => startSync(db));
});
Separately, three things jump out about startSync:
It starts all its operations in parallel, not sequentially
It exhibits the promise creation anti-pattern. There's no reason for startSync to create a new promise; it already has a promise it can work with
It ensures that its resolution value is undefined
If you really want the operations running in parallel like that, I suggest being more explicit about it:
function startSync(db) {
return Promise.all([
syncCats(db),
syncTrees(db),
syncCars(db)
])
.then(_ => undefined); // This does #3
}
...but you could also do to avoid the anti-pattern:
// Still run in parallel!
function startSync(db) {
return syncCats(db)
.then(syncTrees(db))
.then(syncCars(db))
.then(_ => undefined); // Does #3
}
If you meant for them to be sequential, you need to pass functions, not the result of calling them:
function startSync(db) {
return syncCats(db)
.then(_ => syncTrees(db))
.then(_ => syncCars(db))
.then(_ => undefined); // Again, does #3
}
If you made syncCats, syncTrees, and syncCars resolve their promises with db, like this:
function syncCats(db) {
return startSomethingAsync().then(_ => db);
}
...then it could be:
function startSync(db) {
return syncCats(db)
.then(syncTrees)
.then(syncCars)
.then(_ => undefined); // Only here for #3
}
...since each would receive db as its first argument.
Finally, if you don't need to force undefined as the promise resolution value, I suggest dropping that part from the above. :-)
With appreciation to T.J and Jaromanda, I was able to solve it by fixing how startSync() was resolved:
function startSync(db) {
var promise = new Promise(function(resolve, reject) {
syncCats(db)
.then(syncTrees(db)) // not correct way to call, see below
.then(syncCars(db))
...
.then(function() { resolve(); });
});
return promise;
}
Now, as T.J points out, the way each of the .then's is being called is incorrect. He explains it better in his answer. I'm being saved by some misunderstood database layer queueing. syncTrees() and syncCars() should be running in parallel.
If I understood it correctly, you will be having an array of databases and you want to sync them one by one i.e. sync for dbs[0], once that is complete sync for dbs[1], and so on. If that's correct you can do something like this.
var syncMultipleDBs = (dataBases) {
var db = dataBases.shift();
if (!db) {
return;
}
startSync(db).then(syncMultipleDBs.bind(null, dataBases));
};
syncsyncMultipleDBs(dbs.slice());
I hope this will help.
I have got a javascript code like this:
function justTesting() {
promise.then(function(output) {
return output + 1;
});
}
var test = justTesting();
I have got always an undefined value for the var test. I think that it is because the promises are not resolved yet..there is a way to return a value from a promise?
When you return something from a then() callback, it's a bit magic. If you return a value, the next then() is called with that value. However, if you return something promise-like, the next then() waits on it, and is only called when that promise settles (succeeds/fails).
Source: https://web.dev/promises/#queuing-asynchronous-actions
To use a promise, you have to either call a function that creates a promise or you have to create one yourself. You don't really describe what problem you're really trying to solve, but here's how you would create a promise yourself:
function justTesting(input) {
return new Promise(function(resolve, reject) {
// some async operation here
setTimeout(function() {
// resolve the promise with some value
resolve(input + 10);
}, 500);
});
}
justTesting(29).then(function(val) {
// you access the value from the promise here
log(val);
});
// display output in snippet
function log(x) {
document.write(x);
}
Or, if you already have a function that returns a promise, you can use that function and return its promise:
// function that returns a promise
function delay(t) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve();
}, t);
});
}
function justTesting(input) {
return delay(100).then(function() {
return input + 10;
});
}
justTesting(29).then(function(val) {
// you access the value from the promise here
log(val);
});
// display output in snippet
function log(x) {
document.write(x);
}
What I have done here is that I have returned a promise from the justTesting function. You can then get the result when the function is resolved.
// new answer
function justTesting() {
return new Promise((resolve, reject) => {
if (true) {
return resolve("testing");
} else {
return reject("promise failed");
}
});
}
justTesting()
.then(res => {
let test = res;
// do something with the output :)
})
.catch(err => {
console.log(err);
});
Hope this helps!
// old answer
function justTesting() {
return promise.then(function(output) {
return output + 1;
});
}
justTesting().then((res) => {
var test = res;
// do something with the output :)
}
I prefer to use "await" command and async functions to get rid of confusions of promises,
In this case I would write an asynchronous function first,
this will be used instead of the anonymous function called under "promise.then" part of this question :
async function SubFunction(output){
// Call to database , returns a promise, like an Ajax call etc :
const response = await axios.get( GetApiHost() + '/api/some_endpoint')
// Return :
return response;
}
and then I would call this function from main function :
async function justTesting() {
const lv_result = await SubFunction(output);
return lv_result + 1;
}
Noting that I returned both main function and sub function to async functions here.
Promises don't "return" values, they pass them to a callback (which you supply with .then()).
It's probably trying to say that you're supposed to do resolve(someObject); inside the promise implementation.
Then in your then code you can reference someObject to do what you want.
I think what the original poster wants is to return an unwrapped value from a promise without actually returning another promise. Unless proven otherwise, I'm afraid this is not possible outside of a then() or async/await context. You always get a promise no matter what.
You need to make use of reference data type like array or object.
function foo(u,n){
let result = [];
const userBrands = new Promise((res, rej)=> {
res(['brand 1', 'brand 3']);
})
userBrands.then((ub)=>{
return new Promise((res, rej) =>{
res([...ub, 'brand 4', 'brand 5']);
})
}).then(response => {
return result.push(...response);
});
return result;
};
foo();
You cannot return value after resolving promise. Instead call another function when promise is resolved:
function justTesting() {
promise.then(function(output) {
// instead of return call another function
afterResolve(output + 1);
});
}
function afterResolve(result) {
// do something with result
}
var test = justTesting();