我是 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。我认为这可能是超时问题或类似问题。
答案 0 :(得分:4)
代码:每个回调有两个单独的awaited
promise
。 getConfig
返回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
,则需要将其包装在一个确实返回承诺的函数中。