Array.Prototype ForEach等待回调函数以递归函数返回

时间:2019-04-02 10:32:52

标签: javascript node.js loops asynchronous

我有一个递归函数,可循环遍历javascript对象的键。这用于查找名称为“ filename”的所有密钥。当条件匹配时,我需要调用一个回调函数base64,它将图像转换为base64。我的问题是此任务需要很长时间,并且由于它的异步性,循环甚至在转换第一个图像之前就已完成。我试过使用异步库,但是没有用,由于函数的递归性质,我敢肯定它是有效的。在回调返回结果之前,如何停止foreach循环的执行。

功能是

const iterate = (obj) =>
{
    Object.keys(obj).forEach((key) =>
    {
        if(key === 'filename')
        {
            base64.encode(`https://example.com/${obj[key]}`, { string: true }, (errr, encr) =>
            {
                obj[key] = encr;
            });
        }
        if(typeof obj[key] === 'object' && obj[key] !== null)
        {
            iterate(obj[key]);
        }
    });
};

2 个答案:

答案 0 :(得分:0)

您可以promisify方法,然后等待。

 const Promise  = require('bluebird');
    let encode = Promise.promisify(base64.encode)

    const iterate = async (obj) =>
    {
        Object.keys(obj).forEach((key) =>
        {
            if(key === 'filename')
            {
                        obj[key] = await encode(`https://example.com/${obj[key]}`, { string: true });
            }
            if(typeof obj[key] === 'object' && obj[key] !== null)
            {
                iterate(obj[key]);
            }
        });
    };

答案 1 :(得分:0)

//  SOLUTION 1
const async = require('async');

const iterator = (key, next) => {
  if(key === 'filename') {
      base64.encode(`https://example.com/${obj[key]}`, { string: true }, (errr, encr) => {
          obj[key] = encr;
          return next();
      });
  }
  return next();
};

async.each(Object.keys(obj), iterator, err => callback(err, obj));

您可以像这样使用async库。 iterator遍历键,如果键是file

//  SOLUTION 2
const getObj = (obj, callback) => {
    const { filename } = obj;
    if(!filename) return callback(null, obj);
    base64.encode(`https://example.com/${obj['filename']}`, { string: true }, (errr, encr) => {
      obj['filename'] = encr;
      return callback(errr, obj);
    });
};

getObj(obj, (err, newObj) => {
  // use any callback function that uses variable newObj
  // you can change obj by commenting out the line below
  // obj = newObj
}); 

或者因为obj是一个对象,所以您可以直接查找键并将其用于运行回调的函数中。