NodeJS异步/等待订单不起作用

时间:2018-07-30 09:36:59

标签: javascript node.js async-await es6-promise

我是 NodeJS Promises 的新手,所以我可能并不了解它的工作原理。

我正在将配置文件加载到我的应用中,其独特之处在于如果不存在该配置文件,则会使用调用数据库中的信息来创建它。

function getConfig(clientId, app) {
  return new Promise(async (resolve, reject) => {
    await fs.access(config.files.url_networks_file, async function(err) {
      if (err) {
        try {
          await loadClientConfig(clientId);
        } catch (e) {
          reject(e);
        }
      }
    });

    fs.readFile(config.files.url_networks_file, 'utf8', function(err, data) { // Try to read network's configuration file
      if (err) { // If file doesn't exists
        reject(err);
      } else if (JSON.parse(data)[app]) { // In case app's config exists
        resolve(JSON.parse(data)[app]);
      } else { // In case app's config doesn't exists
        reject(new Error('There\'s no configuration for app: ' + app));
      }
    });
  });
}

我的问题是fs.readFile()不会等到loadClientConfig()完成,所以它总是返回“找不到文件”。如果配置文件已经存在,则可以正常运行。

我尝试将fs.readFile()放在fs.access()回调中,但仍然没有得到任何结果(即使文件存在)。

更新

仍然无法使用我收到的两个解决方案。我要发布为每个代码制作的代码,以检查代码中是否丢失了某些内容:

@Quentin

async function loadClientConfig(clientId) {
    return new Promise((resolve, reject) => {
        fs.access(config.files.url_networks_file, function (err) {
            if (err) {
                try {
                    sql.close();
                    sql.connect(config.database.credentials, function (err) {
                        if (err) {
                            reject(err);
                        } else {
                            var request = new sql.Request();
                            request.input('clientId', clientId);
                            query = config.database.queries.all;

                            request.query(query, function (e, data) {
                                if (e) {
                                    reject(e);
                                } else {
                                    try {
                                        resolve(writeConfigFile(data.recordset));
                                    } catch (err) {
                                        reject(err);
                                    }
                                }
                            });
                        }
                    });
                } catch (e) {
                    reject(e);
                }
            }
        });
    });
};

async function getConfig(clientId, app) {
  return new Promise(async (resolve, reject) => {
    try {
      await loadClientConfig(clientId);
    } catch (e) {
      reject(e);
    }

    fs.readFile(config.files.url_networks_file, 'utf8', function(err, data) { // Try to read network's configuration file
      if (err) { // If file doesn't exists
        reject(err);
      } else if (JSON.parse(data)[app]) { // In case app's config exists
        resolve(JSON.parse(data)[app]);
      } else { // In case app's config doesn't exists
        reject(new Error('There\'s no configuration for app: ' + app));
      }
    });
  });
}

@dasfdsa

async function loadClientConfig(clientId) {
  return new Promise((resolve, reject) => {
    sql.close();
    sql.connect(config.database.credentials, function(err) {
      if (err) {
        reject(err);
      } else {
        var request = new sql.Request();
        request.input('clientId', clientId);
        query = config.database.queries.all;

        request.query(query, async function(e, data) {
          if (e) {
            reject(e);
          } else {              
            try {
              resolve(writeConfigFile(data.recordset));
            } catch (err) {
              reject(err);
            }
          }
        });
      }
    });
  });
};

async function getConfig(clientId, app) {
  await new Promise((resolve, reject) => {
    fs.access(config.files.url_networks_file, async function (err) {
      if (err) {
        try {
          let temp = await loadClientConfig(clientId); /*Now that you told me its async, we will await it as well*/
          resolve(temp);
        } catch (e) {
          reject(e);
        }
      } else {
        resolve();
      }
    });
  });
  let configuration = await new Promise((resolve, reject) => {
    fs.readFile(config.files.url_networks_file, 'utf8', function (err, data) { // Try to read network's configuration file
      if (err) { // If file doesn't exists
        reject(err);
      } else if (JSON.parse(data)[app]) { // In case app's config exists
        resolve(JSON.parse(data)[app]);
      } else { // In case app's config doesn't exists
        reject(new Error('There\'s no configuration for app: ' + app));
      }
    });
  });

  return configuration;
}

更新2

似乎在调试时有效,我正在使用VSCode。我认为这可能是超时问题或类似问题。

2 个答案:

答案 0 :(得分:4)

代码:每个回调有两个单独的awaited promisegetConfig返回promise,它将解析为config

async function getConfig(clientId, app) {
    await new Promise((resolve, reject) => {
        fs.access(config.files.url_networks_file, async function (err) {
            if (err) {
                try {
                    let temp = await loadClientConfig(clientId);/*Now that you told me its async, we will await it as well*/
                    resolve(temp);
                } catch (e) {
                    reject(e);
                }
            }
        });
    });
    let config = await new Promise((resolve, reject) => {
        fs.readFile(config.files.url_networks_file, 'utf8', function (err, data) { // Try to read network's configuration file
            if (err) { // If file doesn't exists
                reject(err);
            } else if (JSON.parse(data)[app]) { // In case app's config exists
                resolve(JSON.parse(data)[app]);
            } else { // In case app's config doesn't exists
                reject(new Error('There\'s no configuration for app: ' + app));
            }
        });
    });

    return config;

}

编辑:我已经编辑过等待loadClientConfig()的代码,如果loadClientConfig返回promise,上面的代码应该可以正常工作。

答案 1 :(得分:2)

您只能await个诺言。

fs.access不返回promise(而是使用回调)。 (由于您未在问题中包含该功能,因此无法判断loadClientConfig的功能。

如果您想await,则需要将其包装在一个确实返回承诺的函数中。