异步等待Promise.all Array.map行为异常。不确定为什么

时间:2019-02-18 23:35:09

标签: javascript node.js es6-promise

在我的一个项目中,我在异步函数中具有以下内容。 matchCameramatchIPmatchAudio都返回布尔值或错误。

如果返回错误,我希望它会落入我的主捕获中,这样我就可以处理它,但这没有发生。

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 :(得分:1)

  

Promise.all()方法返回一个Promise,当作为可迭代对象传递的所有promise已解决或当可迭代对象不包含promise时,该Promise进行解析。它以第一个承诺被拒绝的理由拒绝。

您无法达到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返回一个值数组。

答案 1 :(得分:1)

问题是您的matchIP函数包含其中

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

因此,它将错误作为值返回,而不是将其抛出以供外部块捕获。

也正如其他人指出的那样。通过在Promise.all函数中使用await,您几乎是在击败map的价值。取出await s。

答案 2 :(得分:0)

在这种情况下,您无需使用异步/等待,只需返回promise,语句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);
}