#javascript #node.js #scope
#javascript #node.js #область видимости
Вопрос:
Что-то не так с моей областью видимости, которую я здесь не совсем понимаю. У меня есть следующий пример кода:
/**
* Created by David on 10/9/2016.
*/
var public = {};
//REQUIRES
var fs = require('fs');
var rl = require('readline');
//========================================
var configFile = './config';
public.configFile = configFile;
//========================================
public.readSettingsFile = function(conFile){
return new Promise(function(resolve,reject){
try {
console.log("Importing Settings");
//read configuration file line by line
var lineStream = rl.createInterface({
input: fs.createReadStream(conFile === undefined ? configFile : conFile)
});
lineStream.on('line', function (line) {
if(!line.startsWith('#')){
var splitLine = line.split('=');
switch(splitLine[0]){
case 'version':
public.version = splitLine[1];
break;
case 'basePath':
public.basePath = splitLine[1];
break;
}
}
resolve(public);
});
}catch(err){
reject(err);
}
});
}
//========================================
module.exports = public;
Я ожидал бы, что с обещаниями, что в файле .then p должен вернуться после успешного чтения установочного файла, этот public.version теперь должен быть включен, но он возвращает следующее:
{ configFile: './config', readSettingsFile: [Function] }
Консоль.войдите в систему, оператор switch правильно возвращает:
0.1
Комментарии:
1. Вы даже не вызвали
public.readSettingsFile
функцию. Когда вы это сделаете, вы обнаружите, что ваш код readline является асинхронным.2. Многое из того, что вы делаете, неясно и неполно. Где вы на самом деле вызываете файл readSettingsFile, например? Ваше обещание также не возвращает результат в случае успеха.
3. Извините, отредактировано, чтобы попытаться придать ему больше смысла
4. @zerkms, мне интересно, учитывая то, как я настроил обещание, оно все еще действует асинхронно, поэтому возвращает действительное обещание, несмотря на то, что я не закончил чтение?
5.
new Promise(function(resolve,reject){ reject(err); });
простоPromise.reject(err)
.
Ответ №1:
Я думаю, что ваша проблема не в «области видимости», но вы не понимаете, как использовать обещания. Я настоятельно рекомендую как документацию Mozilla, так и сообщение в блоге Дэвида Уолша. Я также рекомендую вам начать с малого и написать несколько простых обещаний, прежде чем пробовать что-то более сложное.
Теперь я отвечу на ваш конкретный вопрос. Причина, по которой вы не видите того, что хотите видеть, заключается в том, что весь ваш бизнес linestream является асинхронным. Вы возвращаете обещание в конце своей функции, прежде чем перейти к оператору switch. В принципе, думайте о promise как о целой функции. Но вместо того, чтобы возвращать значение, вы возвращаете обещание значения или ошибки. Если вы вводите обещание в середине функции, ваша функция пытается сделать слишком много вещей, и вам нужно больше отделять свой код.
Это должно быть ближе к тому, что вы хотите. Это не идеальный код, и он может не соответствовать вашим потребностям, но, надеюсь, он поможет вам на правильном пути. Удачи.
public.readSettingsFile = function(conFile){
return new Promise(function(resolve, reject) {
var lineStream = rl.createInterface({
input: fs.createReadStream(conFile === undefined ? configFile : conFile)
});
lineStream.on('line', function (line) {
if(!line.startsWith('#')){
var splitLine = line.split('=');
// You don't need a switch statement for only one case
if (splitLine[0] === 'version') {
public.version = splitLine[1];
console.log(public.version);
// You actually have to resolve something
resolve(public);
} else {
// There's a problem, reject it.
reject("Some error message");
}
});
}
}
Ответ №2:
Код, который у меня был, на самом деле был в основном правильным, но, как упомянул Пол в своем ответе, решение было в неправильном месте. lineStream.on выполнялся асинхронно, и разрешение находилось за пределами его завершения, поэтому он выполнял путь «разрешения» без фактического правильного завершения.