Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to call an asynchronous function within map?

I'm mapping over an array and for one of the return values of the new object, I need to make an asynchronous call.

var firebaseData = teachers.map(function(teacher) {   return {     name: teacher.title,     description: teacher.body_html,     image: urlToBase64(teacher.summary_html.match(/src="(.*?)"/)[1]),     city: metafieldTeacherData[teacher.id].city,     country: metafieldTeacherData[teacher.id].country,     state: metafieldTeacherData[teacher.id].state,     studioName: metafieldTeacherData[teacher.id].studioName,     studioURL: metafieldTeacherData[teacher.id].studioURL   } }); 

The implementation of that function will look something like

function urlToBase64(url) {   request.get(url, function (error, response, body) {     if (!error && response.statusCode == 200) {       return "data:" + response.headers["content-type"] + ";base64," + new Buffer(body).toString('base64');     }   }); } 

I'm not clear what's the best approach to do this... promises? Nested callbacks? Use something in ES6 or ES7 and then transpile with Babel?

What's the current best way to implement this?

like image 237
magician11 Avatar asked Oct 30 '15 14:10

magician11


People also ask

Can we use async function inside map?

If you use the async await function and console out the output, then you will find the arrays of promises that are still needed to be resolved. The map doesn't resolve the promises on its own but left the stuff for the developer to resolve. So, that means you can't use async-await in the map.

How do you call an asynchronous function?

Inside an async function, you can use the await keyword before a call to a function that returns a promise. This makes the code wait at that point until the promise is settled, at which point the fulfilled value of the promise is treated as a return value, or the rejected value is thrown.

Is array map asynchronous?

The . map() algorithm applies an async callback to each element of an array, creating promises as it does. However, the returned result by . map() is no promise, but an array of promises.

Is array map synchronous?

A Array. map() is a very useful function but, unfortunately, it only works with synchronous functions. A simple workaround for using async map functions is to use Promose.


1 Answers

update in 2018: Promise.all async function within map callback is easier to implement:

    let firebaseData = await Promise.all(teachers.map(async teacher => {         return {             name: teacher.title,             description: teacher.body_html,             image: await urlToBase64(teacher.summary_html.match(/src="(.*?)"/)[1]),             city: metafieldTeacherData[teacher.id].city,             country: metafieldTeacherData[teacher.id].country,             state: metafieldTeacherData[teacher.id].state,             studioName: metafieldTeacherData[teacher.id].studioName,             studioURL: metafieldTeacherData[teacher.id].studioURL         }     }));   async function urlToBase64(url) {   return request.get(url, function (error, response, body) {     if (!error && response.statusCode == 200) {       return "data:" + response.headers["content-type"] + ";base64," + new Buffer(body).toString('base64');     }   }); } 

Edit@2018/04/29: I put the general example for everyone:

Edit@2019/06/19 : async/await should have try/catch to handle error: it would throw a warning message if error occur;

let data = await Promise.all(data.map(async (item) => {       try {       item.fetchItem = await fetchFunc(item.fetchParams);        return item;        } catch(err) {          throw err;       }   })); 
like image 98
Kai Avatar answered Sep 27 '22 19:09

Kai