Run a function against each object in an array in parallel? [duplicate] - javascript

This question already has answers here:
Wait until all promises complete even if some rejected
(20 answers)
Closed 2 months ago.
I have an array
var array = ["First","Second","Third"]
let i = 0;
I want it to run each object in the array across the same async functions at the same time
for (;i < arbAgainstLength;) {
const first = async () => {
//do some await stuff
}
const second = async (param1, param2) => {
//do other await stuff
}
}
This bot is monitoring price changes, so I'm looking for it to only take action on a specific object at the time that object meets the proper criteria.
So, if First meets the criteria, it will complete the rest of the sequence, but Second and Third will continue to listen.
Then, finally, once the sequence is complete for an object, I'd like to put that object BACK into the async functions.
Currently, and this is probably expected, the function only runs fully if it's the last object in the array
Is it possibly a forEach instead of a for? Or is a promise needed as well?
I have tried async.parallel and promises. If the answer is a promise, I think I may be still trying to grasp how they work exactly.

I think there was a lack of proper verbage in my question but I ended up finding that it was best used as a promise.all with a forEach inside it.
Thanks for all that!

Related

Run asynchronous JavaScript functions inside a forEach loop synchronously [duplicate]

This question already has answers here:
Resolve promises one after another (i.e. in sequence)?
(36 answers)
Closed 2 years ago.
I'm developing an app and I'm having a problem. I want to run two functions inside a forEach loop, which means for each iteration run both functions once.
This is very simple to do when you think about it, but my functions are asynchronous and my first function needs to finish before the second one executes.
Reason why i made these functions async is that in my app these functions represent an API call.
I will show you a quick example in which i used setTimeout() instead of API calls.
async function f(){
await setTimeout(()=>{
console.log("FIRST")
},1000)
}
async function f2(){
await setTimeout(()=>{
console.log("SECOND")
},3000)
}
for(var i = 0;i < 5; i++){
f()
f2()
}
When I run this the output is:
FIRST
FIRST
FIRST
FIRST
FIRST
SECOND
SECOND
SECOND
SECOND
SECOND
And i need my output to be:
FIRST
SECOND
FIRST
SECOND
FIRST
SECOND
FIRST
SECOND
FIRST
SECOND
Any idea how to achieve this? Would be very helpful.
Wait for the first async function to finish and then call the second one
for(var i = 0;i < 5; i++){
f1().then(res => {
return f2()
}
}
This will not guarantee your desired output, but will guarantee that a call to f2 was done after a call to f1
Note: you could collect all promises into an array and maybe call Promise.all if you want to know when all of them are finished.

How this works? I can't understand this snippet [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
let unrealFunctionToUnderstand = () => {
let tryToUnderstandThis = () => 666;
console.log('I\'m calling once time! :D');
return tryToUnderstandThis;
}
let hardcoreLesson = unrealFunctionToUnderstand();
console.log(hardcoreLesson());
console.log(hardcoreLesson());
I cant understand this code, my friend send me this...
unrealFunctionToUnderstand is a function. When called it logs "I'm calling once time! :D".
It also returns another function (tryToUnderstandThis) when called.
After defining this function you are (1) calling it unrealFunctionToUnderstand(), then (2) assigning it's returned value (tryToUnderstandThis) to hardcoreLesson. Then you are calling hardcoreLesson (reference to tryToUnderstandThis) twice and logging the result.
So you are calling unrealFunctionToUnderstand once, and it logs "I'm calling once time! :D", then calling tryToUnderstandThis twice, and it logs "666" twice.
Can you notice how I "ran" this code on paper? This is how you answer questions like this yourself. You interpret the code the same way the browser would, on paper. It becomes easier to pinpoint language constructs you don't understand or know yet, so you can first learn / ask about those. Then, if you understand each part, it becomes clear what is executed and why.
everything in javascript is an object, including functions. Which means you can return a function from a function.
That is exactly what unrealFunctionToUnderstand() is - it is a function which returns a function.
So, you call it once:
let hardcoreLesson = unrealFunctionToUnderstand();
Hence the console output only displays once. And you now have a reference to a function which simply returns the value 666.
let tryToUnderstandThis = () => 666;
....
return tryToUnderstandThis;
When you execute that, you get back the response.
hardcoreLesson store the value return by this function unrealFunctionToUnderstand.
So unrealFunctionToUnderstand calling only one time.
as hardcoreLesson store the value it's shows 2 times as it's called two time.
If you are familiar with any other programming language like C or Java, then you will be familiar with the following syntax.
function functionName(argument1, argument2, ...) {
// function body
// return statement
}
The new version of javascript introduces the arrow operator => to reduce your effort of writing single line functions. This is similar to lamda/inline function used mostly for single line functions.
So if you have a following function
function increment (value) {
return value + 1;
}
you can replace it with
increment(value) => value + 1
The other answers should help you understand how the function are also objects and how it can be called in different ways.
Some helpful links
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-closure-b2f0d2152b36

I can't access object inside array even though it exists [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
This method stores JSON objects retrieved from a firebase database to array scores.
function loadScoresToArray(){
databaseRef.orderByChild("Score").on("child_added", function (snap) {
scores.push(snap.val());
});
}
Run the above method and print content of scores
loadScoresToArray();
console.log(scores);
console.log(scores[0]);
output
As seen here, objects have correctly been added to scores.
But I can't retrieve them using index.
Reading similar questions like this I think this might be because when console.log(scores[0]); is called, the array is still empty. It has not been populated yet. This is just my guess.
How do I solve this? Is there a way to create a delay until the array is populated?
But I can't retrieve them using index.
That's because you're performing an asynchronous operation. Instead of waiting for the response, the execution continues immediately and the statement after the request call is execute.
How do I solve this? Is there a way to create a delay until the array
is populated?
No, don't use a delay. You can use a callback function.
function loadScoresToArray(callback){
databaseRef.orderByChild("Score").on("child_added", function (snap) {
scores.push(snap.val());
callback(scores);
});
}
loadScoresToArray(function(scores){
console.log(scores[0]);
});
Another solution is to use Promise constructor in order to perform an asynchronous operation.
function loadScoresToArray(){
return new Promise(function(resolve, reject){
databaseRef.orderByChild("Score").on("child_added", function (snap){
scores.push(snap.val());
resolve(scores);
});
});
}
loadScoresToArray().then(function(scores){
console.log(scores[0]);
});
Here are possible approaches in order to solve your problem.
Promises with async/await (ES2017+)
Callbacks
Promises with then() (ES2015+)

Will my map function always run first [duplicate]

This question already has answers here:
Are all javascript callbacks asynchronous? If not, how do I know which are?
(5 answers)
Closed 6 years ago.
Will the map function always finish running before the if statement runs? I want to make sure that the elements in the array are always added up before the if statement runs. Will there ever be a time when the map function doesn't finish running before the if statement starts and so the if statement will not get the true value of the add variable?
var arr = [ '33.3%', '33.3%', '33.3%' ];
var add = 0;
arr.map(function(elem){
add += parseInt(parseFloat(elem)*10000)
});
if (add <= 1001000 && add >= 999000) {
console.log("passed!!")
}
Yes. Unless you have asynchronous requests or multi-threaded operations like WebWorkers, your code is synchronous, i.e. it is executed in strict order.
Array.prototype.map of javascript is synchronous, but if you want an async behaviour you can use nodejs async module.
NodeJS Async Map
var async = require('async');
var arr = ['1','2'];
async.map(arr, getInfo, function (e, r) {
console.log(r);
});
function getInfo(name, callback) {
setTimeout(function() {
callback(null, name + 'new');
}, 1000);
}
http://code.runnable.com/UyR-6c2DZZ4SmfSh/async-map-example-for-node-js

Is there a simple way to determine if Protractor is returning a promise? [duplicate]

This question already has an answer here:
Checking if an object is a promising function
(1 answer)
Closed 7 years ago.
I am hoping for any quick way (hopefully one that I can use in many/all instances) to verify that a selector is returning a promise and not an element.
A hack solution might be something like:
var result = something.getSomething(someArgs);
if(result.then){
// it's a promise.
}else{
// the usual stuff.
}
the right way might be using instanceof, I believe protractor promises are of type webdriver.promise.Promise( would like some confirmation on this point), a simple checking method might be:
function isPromise(obj){
return obj instanceof webdriver.promise.Promise || webdriver.promise.isPromise(obj);
}
//usage
var result = something.getSomething(someArgs);
if(isPromise(result))){
// it's a promise.
}else{
// the usual stuff.
}
Your best bet if you are not sure if something is a promise or not is to use promise.when() to turn it into a promise if it is not already one, and thus you can treat the result as a promise safely.
But most things in protractor seem to return promises that I have seen, so this should be a redundant operation in most cases.

Categories

Resources