Async Await Promise.all Array.map работает не так, как ожидалось.Не уверен почему - PullRequest
0 голосов
/ 19 февраля 2019

У меня есть ниже в асинхронной функции в одном из моих проектов.matchCamera, matchIP и matchAudio все возвращают либо логическое значение, либо ошибку.

Если ошибка будет возвращена, я ожидаю, что она попадет в мою главную ловушку, так что я смогу ее обработать, ноэтого не происходит.

try {
    // .... Additional code here

    const typecheck = await Promise.all(
        evoCfg.cameras.map(async camera => {
            if (camera.type === 'H264') {
                return await matchCamera(camera);
            } else if (camera.type === 'RTSP') {
                return await matchIP(camera);
            } else if (camera.type === 'AUDIO') {
                return await matchAudio(camera);
            } else {
                // Motion JPEG
                return true;
            }
        })
    );

    //  .... additional code here

    console.log('results:);
    console.dir(typecheck, {depth: null, colors: true});
} catch (e) {
    console.error('In Master Catch:', e);
}

Мой вывод, который я продолжаю получать при возникновении условия ошибки:

results:
[ true,
true,
true,
true,
true,
true,
Error: MAC for IP Cam not found on Network: 00:11:22:33:44:55
  at matchIP (/file.js:58:15)
  at process._tickCallback (internal/process/next_tick.js:68:7),
true ]

Я ожидаю:

In Master Catch: MAC for IP Cam not found on Network: 00:11:22:33:44:55
  at matchIP (/file.js:58:15)
  at process._tickCallback (internal/process/next_tick.js:68:7)

const matchIP = async source => {
    let arpScan = [];

    for (const c in obj.arr){
        if(obj.arr[c].name === source.source) {
            try {
                arpScan = await scannerP();

                let arpIdx = searchObjArray(source.mac, source.mac, 'mac', 'mac', arpScan);
                if(arpIdx === -1) {
                    // not found on network
                    throw new Error(`MAC for IP Cam not found on Network: ${source.mac}`);
                }

                for (const cs in obj.arr[c].sources) {
                    if (
                        obj.arr[c].sources[cs].id === arpScan[arpIdx].mac &&
                        obj.arr[c].sources[cs].url === `rtsp://${arpScan[arpIdx].ip}/${source.streamPort}`
                        ) {
                        return true;
                    }
                }
                let recorderIdx = searchObjArray(
                    'rtsp',
                    source.mac,
                    'fmt',
                    'id',
                    obj.arr[c].sources
                );

                source.streamAddress = arpScan[arpIdx].ip;
                obj.arr[c].sources[recorderIdx].url = `rtsp://${arpScan[arpIdx].ip}/${source.streamPort}`;
                return false;
            } catch (e) {
                return e;
            }
        }
    }
};

Ответы [ 3 ]

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

Метод Promise.all () возвращает одно Обещание, которое разрешается, когда все обещания, переданные как итеративные, разрешены или когда итерация не содержит обещаний.Он отклоняет причину первого обещания, которое отклоняет.

Вы побеждаете цель Promise.all.Он ожидает список обещаний, но вы предоставляете список значений из обещания.

const typecheckArray = await Promise.all(
  evoCfg.cameras.map(camera => {
    if (camera.type === 'H264') {
      return matchCamera(camera);
    } else if (camera.type === 'RTSP') {
      return matchIP(camera);
    } else if (camera.type === 'AUDIO') {
      return matchAudio(camera);
    } else {
      // Motion JPEG
      return Promise.resolve(true);
    }
  })
);

Кроме того, Promise.all возвращает массив значений.

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

Проблема в том, что ваша функция matchIP содержит

try {
  // ... code
catch (e) {
  return e;
}

Так что она возвращает ошибку в виде значения, а не выдает ее для перехвата внешнего блока.

Также, как указали другие люди.Вы в основном побеждаете значение Promise.all, используя await в своей функции map.Возьмите await с.

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

В этом случае вам не нужно использовать async / await, просто верните обещание, и оператор Promise.all обработает это

try {
    // .... Additional code here

    const typecheck = await Promise.all(
        evoCfg.cameras.map(camera => {
            if (camera.type === 'H264') {
                return matchCamera(camera);
            } else if (camera.type === 'RTSP') {
                return matchIP(camera);
            } else if (camera.type === 'AUDIO') {
                return matchAudio(camera);
            } else {
                // Motion JPEG
                return true;
            }
        })
    );

    //  .... additional code here

    console.log('results:);
    console.dir(typecheck, {depth: null, colors: true});
} catch (e) {
    console.error('In Master Catch:', e);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...