简体   繁体   English

全局变量在forEach循环体内显示为“意外标识符”

[英]Global Variable showing up as “unexpected identifier” inside body of forEach loop

I have some Javascript code that I am trying to refactor. 我有一些我试图重构的Javascript代码。 The variable that is giving me problems is the Server variable which is a custom module I created. 给我带来问题的变量是Server变量,它是我创建的自定义模块。 For some reason, when the interpreter tries to evaluate the first line of the forEach loop, the Server variable is coming back as an "unidentified identifier." 出于某种原因,当解释器试图评估forEach循环的第一行时, Server变量将作为“未识别的标识符”返回。 Here is the new refactored code that is not working: 以下是无效的新重构代码:

'use strict';

const Config = require('config');

const Server = require('./server');

let servers = [];

async function start() {
    const services = Config.get('app.services');

    try {
        services.forEach(service => {
            // An error is returned with this next line saying Server is an "unidentified identifier"
            let server = await Server.deployment(service.host, service.port);
            await server.start();
            servers.push(server);
        });
    } catch (err) {
        console.log('an error has been caught');
        console.log(err);
        process.exit(1);
    }

    servers.forEach(server => {
        console.log(`Server running at ${server.info.uri}`);
    });
};

Here is the code that I had before which is working: 以下是我之前使用的代码:

async function start() {
    try {
        // Server works as anticipated here.
        const server = await Server.deployment(Config.get('app.host'), Config.get('app.port'));
        await server.start();
        servers.push(server);

        const server2 = await Server.deployment(Config.get('app.host'), 3031);
        await server2.start();
        servers.push(server2);

    } catch (err) {
        console.log('an error has been caught');
        console.log(err);
        process.exit(1);
    }

    servers.forEach(server => {
        console.log(`Server running at ${server.info.uri}`);
    });
};

As you see here, I want to move my server configurations to a metadata file, then just use the forEach loop to create the server deployments that I need. 如您所见,我想将我的服务器配置移动到元数据文件,然后只需使用forEach循环来创建我需要的服务器部署。

Can anybody explain why this is failing and offer any tips as to how to code this effectively? 任何人都可以解释为什么这会失败并提供有关如何有效编码的任何提示?

EDIT 1: Adding exact error message for clarity. 编辑1:为清晰起见添加确切的错误消息。

let server = await Server.deployment(service.host, service.port); 
                   ^^^^^^ SyntaxError: Unexpected identifier

You can only use await inside an async function - your forEach callback is not async at the moment, so an error is thrown when you try to use await inside. 你只能在async函数中使用await - 你的forEach回调目前不是async的,所以当你尝试使用await inside时会抛出错误。 But simply changing the forEach callback to async probably won't do what you want - instead, map each service initialization to a Promise and call Promise.all on the array of promises. 但是简单地将forEach回调更改为异步可能不会做你想要的 - 而是map每个service初始化mapPromise并在promises数组上调用Promise.all No need for a global servers variable either: 无需全局servers变量:

async function start() {
  const services = Config.get('app.services');
  try {
    const serverPromises = services.map(async (service) => {
      const server = await Server.deployment(service.host, service.port);
      await server.start();
      return server;
    });
    const servers = await Promise.all(serverPromises);
    servers.forEach(server => {
      console.log(`Server running at ${server.info.uri}`);
    });
  } catch (err) {
    console.log('an error has been caught');
    console.log(err);
    process.exit(1);
  }
}

Here's a variation of the other answer that uses a for loop instead of .forEach() so that you can iterate through your servers in sequence rather than doing them all in parallel. 这是另一个使用for循环而不是.forEach()答案的变体,这样您就可以按顺序遍历服务器而不是并行执行。 Unlike .forEach() , a for loop inside an async function will pause for await . .forEach()不同, async函数中的for循环将暂停await It also makes the code a bit simpler. 它还使代码更简单。

async function start() {
  const services = Config.get('app.services');
  const servers = [];
  try {
    for (let service of services) {
      const server = await Server.deployment(service.host, service.port);
      servers.push(server);
      await server.start();
      console.log(`Server running at ${server.info.uri}`);
    });
  } catch (err) {
    console.log('an error has been caught', err);
    process.exit(1);
  }
  return servers;
}

Either the other answer or this one will work. 要么是其他答案,要么是这个答案。 I just wanted to show you how a for loop can be used with await to simplify things whereas .forEach() will not pause for await . 我只是想告诉你如何使用for循环来await简化,而.forEach()不会暂停await

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM