Как вкладывать обещания (Promise.all внутри Promise.all) - PullRequest
1 голос
/ 20 января 2020

Рассмотрим следующую структуру вложенных Promises:

const getData = async() => {

  const refs = [{
      name: "John33",
      age: 33
    },
    {
      name: "John34",
      age: 34
    },
    {
      name: "John35",
      age: 35
    },
    {
      name: "John36",
      age: 36
    }
  ];


  let source = [{
      name: "John30",
      age: "unknown"
    },
    {
      name: "John31",
      age: "unknown"
    },
    {
      name: "John32",
      age: "unknown"
    },
    {
      name: "John33",
      age: "unknown"
    },
    {
      name: "John34",
      age: "unknown"
    },
    {
      name: "John35",
      age: "unknown"
    }, {
      name: "John36",
      age: "unknown"
    },
    {
      name: "John37",
      age: "unknown"
    },
    {
      name: "John38",
      age: "unknown"
    },
    {
      name: "John39",
      age: "unknown"
    }
  ];

  const resolver = doc => {
    return new Promise(doc => {
      let clone = { ...doc
      };
      let found = refs.find(ref => {
        return ref.name === doc.name;
      });

      if (found) clone.age = found.age;
      return clone;
    });
  };

  let getRefs = (doc, refs) => {
    const promises = refs.map(r => {
      resolver(doc).then(result => {
        return result;
      });
    });

    return Promise.all(promises);
  };


  let getCursorData = (cursor, refs, data) => {
    const promises = cursor.forEach(doc => {
      console.log("Getting cursor for " + doc.name);
      let clone = { ...doc
      };

      return getRefs(clone, refs).then(result => {
        console.log("Getting refs for " + clone.name);
        data.push(result);
      });
      return;
    });

    return Promise.all(promises);
  };

  // Get data
  let data = [];
  await getCursorData(source, refs, data);

  console.log("Returned data: ");
  console.log(data);

  return data;
};

console.log("Begin");
getData().then(result => {
  console.log("End");
  console.log(result)
});

По какой-то причине я не дошел до конца кода (End не печатается). Я подозреваю, что есть какая-то позиция или отсутствует возврат, но я застрял, не найдя решения.

Как я могу заставить эту структуру кода работать, как ожидалось, следующим образом:

  1. Итерировать через источник (мои данные, которые поступают из базы данных
  2. Для каждого регистра применяются изменения ссылок (в примере изменение age)
  3. Возврат данных с фиксированными ссылками

Ожидаемый результат этого кода - получить исходные данные (source) с фиксированными доступными ссылками, используя текущие структуры обещаний:

[
      name: "John30",
      age: "unknown"
    },
    {
      name: "John31",
      age: "unknown"
    },
    {
      name: "John32",
      age: "unknown"
    },
    {
      name: "John33",
      age: 33
    },
    {
      name: "John34",
      age: 34
    },
    {
      name: "John35",
      age: 35
    }, {
      name: "John36",
      age: 36
    },
    {
      name: "John37",
      age: "unknown"
    },
    {
      name: "John38",
      age: "unknown"
    },
    {
      name: "John39",
      age: "unknown"
    }
]

1 Ответ

0 голосов
/ 21 января 2020

вот ты go!

const SimulatedDatabaseCall = new Promise(resolve => {
	setTimeout(() => {
		resolve([
			{
				name: 'John33',
				age: 33
			},
			{
				name: 'John34',
				age: 34
			},
			{
				name: 'John35',
				age: 35
			},
			{
				name: 'John36',
				age: 36
			}
		]);
	}, 200);
});

let source = [
	{
		name: 'John30',
		age: 'unknown'
	},
	{
		name: 'John31',
		age: 'unknown'
	},
	{
		name: 'John32',
		age: 'unknown'
	},
	{
		name: 'John33',
		age: 'unknown'
	},
	{
		name: 'John34',
		age: 'unknown'
	},
	{
		name: 'John35',
		age: 'unknown'
	},
	{
		name: 'John36',
		age: 'unknown'
	},
	{
		name: 'John37',
		age: 'unknown'
	},
	{
		name: 'John38',
		age: 'unknown'
	},
	{
		name: 'John39',
		age: 'unknown'
	}
];

async function updateSource(source, SimulatedDatabaseCall) {
	await SimulatedDatabaseCall;
	SimulatedDatabaseCall.then(_database => {
		var sourceMap = source.map(_sourceOBJ => {
			return _sourceOBJ.name;
		});
		_database.forEach(_databaseOBJ => {
			var index = sourceMap.indexOf(_databaseOBJ.name);
			source[index].age = _databaseOBJ.age;
		});
	});

	return source;
}

updateSource(source, SimulatedDatabaseCall).then(_val => {
	console.log(_val);
});
...