Почему Array.map () с async / await возвращает странные результаты? - PullRequest
0 голосов
/ 05 февраля 2019

Вот рабочая версия моего кода, которая возвращает все как положено:

***.then(r => r.json()).then(async r => {

                    for (let i = 0; i < r.length; i++) {
                        let pipeline = r[i];
                        pipeline.collapsed = true;
                        pipeline.levels = await this.getPipelineLevels(pipeline.id);
                    }

                    this.project.pipelines.items = r;
                })

Вот "сломанная" версия, которая возвращает странные результаты:

****.then(r => r.json()).then(r => {
                    let pipelines = r.map(async (value) => {
                        let levels = await this.getPipelineLevels(value.id);
                        return {...value, collapsed: true, levels: levels};
                    });

                    this.project.pipelines.levels = pipelines;

Странный вывод в консоли с console.log(JSON.stringify(pipelines)) после *.map():

[{"_c":[],"_s":0,"_d":false,"_h":0,"_n":false},{"_c":[],"_s":0,"_d":false,"_h":0,"_n":false}]

Что здесь происходит?

Ответы [ 2 ]

0 голосов
/ 05 февраля 2019

Потому что Array.map на самом деле await не передано.Неважно, что вы пометили его обратный вызов как async.

Просто Array.map ваши Обещания, затем передайте их Promise.all и пусть это ждет вас (параллельно) для вас.

const getPipelineLevels = id => new Promise(resolve => {
  setTimeout(() => resolve({ id: id, foo: 'bar' }), 500)
})

const idx = [1,2,3,4,5]

const tasks = idx.map(id => {
  return getPipelineLevels(id)
    .then(value => ({ ...value, bar: 'baz' }))
})

Promise.all(tasks)
  .then(results => {
    console.log(results)
  })
0 голосов
/ 05 февраля 2019

Попробуйте что-то вроде этого:

.then(async r => {
    let pipelines = await Promise.all(r.map(async (value) => {
        let levels = await this.getPipelineLevels(value.id);
        return {...value, collapsed: true, levels: levels};
    }));
    this.project.pipelines.levels = pipelines;
});

Array.map(async (value) => {...}) возвращает массив Обещаний.

Это решение также будет быстрее, чем то, что ОП пытался достичь в любом случаепоскольку он ожидает параллельно.

И обратите внимание, что вам следует избегать ожидания цепочки .then (…) .

...