Javascript Code Running In Wrong Sequence
Solution 1:
It's not clear whether you were using the timeout to substitute some asynch behavior or whether the timeout is integral to what you're trying to solve. We'll get to them both. I'd written about turning setTimeout()
into a promises pattern, in my blog. So, first, turn use of setTimeout()
into a promise-based pattern:
functiontimeout(delay) {
returnnewPromise(
(resolve, reject) =>setTimeout( resolve, delay )
)
} // timeout()
So, step one (kind of) accomplishes what you want:
arr.forEach(function(item) {
timeout(3000)
.then(() => {
item.a = item.a + 1;
newArr.push(item.a)
});
});
console.log(arr[0],arr[1],arr[2], arr[3]);
console.log(newArr);
But notice, that immediately after completion of the forEach()
call, arr
and newArr
have their old values. Eventually, they'll be updated. When can we use updated arr
and newArr
? We need to wait until the values are updated.
var promises=[]
arr.forEach(function(item) {
promises.push(timeout(3000)
.then(() => {
item.a = item.a + 1;
newArr.push(item.a)
})
)
});
Promise.all(promises).then(() =>console.log(arr, newArr))
Collect up the promises and wait on them to all finish... then you know they are "up to date".
Solution 2:
You would do it like this:
Create a function that takes two parameters: a
and arr
and 'newArr' representing the array and a and newArr variables.
This function would act as a recursive function which would set a timeout and then call itself again like this:
var arr = [{a: 1}, {a: 2}, {a: 3}, {a: 4}];
var newArr = [];
var a = 0;
functionrecursiveIterator(a, arr, newArr) {
var b = a;
b++;
var newerArr = newArr;
if (b < arr.length) {
setTimeout(function() {
newerArr.push(arr[b].a);
recursiveIterator(b, arr, newerArr);
}, 1000);
} else {
console.log(newerArr);
}
}
recursiveIterator(a, arr, newArr);
Solution 3:
Get Rid of the setTimeout. REPL
var newArr = [];
var arr = [{a: 1}, {a:2}, {a:3}, {a:4}];
arr.forEach(function(item) {
item.a = item.a + 1;
newArr.push(item.a);
});
console.log(newArr);
Solution 4:
You should make the increment before the timeout
var newArr = [];
var arr = [{a: 1}, {a:2}, {a:3}, {a:4}];
var itemsProcessed = 0;
arr.forEach(function(item) {
setTimeout(function(){item.a = item.a+1;newArr.push(item.a);
itemsProcessed++;
if(itemsProcessed === arr.length) {
console.log(newArr);
}
}, 3000);
});
Solution 5:
You can run your code synchronously via nsynjs:
Here is how your code may look like:
var longRunningFunction = function(ctx,timeout,val) {
var ret={};
setTimeout(function(){
ret.result = val + 1;
ctx.resume();
},timeout);
return ret;
};
longRunningFunction.nsynjsHasCallback = true;
functionmyFunc() {
var newArr = [];
var arr = [{a: 1}, {a:2}, {a:3}, {a:4}];
for(var i=0; i<arr.length; i++) {
var item=arr[i];
item.a = longRunningFunction(nsynjsCtx,1000,item.a).result;
newArr.push(item.a);
}
console.log(JSON.stringify(newArr));
}
nsynjs.run(myFunc,{},function() {
console.log('done');
});
Resulting output will be printed with 4 seconds delay:
[2,3,4,5]
Post a Comment for "Javascript Code Running In Wrong Sequence"