Array.Prototype ForEach Ожидание возврата функции обратного вызова в рекурсивной функции - PullRequest
1 голос
/ 02 апреля 2019

У меня есть рекурсивная функция, которая перебирает ключи объекта javascript.Это используется для поиска всех ключей с именем «имя файла».Когда условие соответствует, мне нужно вызвать функцию обратного вызова 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 ]

1 голос
/ 02 апреля 2019

Вы можете обещать свой метод и затем ждать.

 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]);
            }
        });
    };
0 голосов
/ 02 апреля 2019
//  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 является объектом, вы можете напрямую искать ключ и использовать его в функции, которая выполняетобратный вызов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...