在地图中调用asynchronous函数的最佳方法是什么?

我正在映射一个数组和一个新的对象的返回值,我需要做一个asynchronous调用。

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 } }); 

该函数的实现将看起来像

 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'); } }); } 

我不清楚什么是最好的做法…承诺? 嵌套callback? 使用ES6或ES7中的东西,然后与Babel一起传输?

现在最好的方法是什么来实现呢?

谢谢!

一种方法是Promise.all (ES6) 。

这个答案将在节点4.0+中工作。 旧版本需要一个Promise的polyfill或库。 我还使用了ES6箭头函数,您可以用Node <4的常规functionreplace它。

这个技术手工包装了一个Promise的request.get 。 你也可以使用像request-promise这样的库。

 function urlToBase64(url) { return new Promise((resolve, reject) => { request.get(url, function (error, response, body) { if (!error && response.statusCode == 200) { resolve("data:" + response.headers["content-type"] + ";base64," + new Buffer(body).toString('base64')); } else { reject(response); } }); }) } // Map input data to an Array of Promises let promises = input.map(element => { return urlToBase64(element.image) .then(base64 => { element.base64Data = base64; return element; }) }); // Wait for all Promises to complete Promise.all(promises) .then(results => { // Handle results }) .catch(e => { console.error(e); }) 

你可以使用async.map 。

 var async = require('async'); async.map(teachers, mapTeacher, function(err, results){ // results is now an array of stats for each file }); function mapTeacher(teacher, done) { // computing stuff here... done(null, teacher); } 

注意,所有的老师都将被并行处理 – 你也可以使用这个function:

mapSeries(arr, iterator, [callback])一一映射

mapLimit(arr, limit, iterator, [callback])映射limit在同一时间

我正在使用数组上的asynchronous函数。 而不是使用array.map,而是一个for函数。 这是这样的:

 const resultingProcessedArray = async function getSomeArray() { try { let { data } = await axios({url: '/myUrl', method:'GET'}); //initial array let resultingProcessedArray = []; for (let i = 0, len = data.items.length; i < len; i++) { let results = await axios({url: `/users?filter=id eq ${data.items[i].someId}`, method:'GET'}); let domainName = results.data.items[0].domainName; resultingProcessedArray.push(Object.assign(data.items[i], {domainName})); } return resultingProcessedArray; } catch (err) { console.error("Unable to fetch the data", err); return []; } }; 

2017更多新的库使我的单页应用程序有超过4 megasbuild成。 所以我决定不要添加更多像lodash这样的新库,可以用代码来代替。 我用地图等待好的解决scheme是:

  rows.map ( ( record ) => { try { (async () => { let col = await client.query(`SELECT * FROM customers`); })(); } catch (err) { console.log(err); } });