Eu tenho esse pedaço de código (retirado desta pergunta ):
var walk = function(dir, done) {
var results = [];
fs.readdir(dir, function(err, list) {
if (err)
return done(err);
var pending = list.length;
if (!pending)
return done(null, results);
list.forEach(function(file) {
file = path.resolve(dir, file);
fs.stat(file, function(err, stat) {
if (stat && stat.isDirectory()) {
walk(file, function(err, res) {
results = results.concat(res);
if (!--pending)
done(null, results);
});
} else {
results.push(file);
if (!--pending)
done(null, results);
}
});
});
});
};
Estou tentando segui-lo e acho que entendo tudo, exceto no final, onde diz !--pending
. Nesse contexto, o que esse comando faz?
Edit: Agradeço todos os comentários, mas a pergunta foi respondida muitas vezes. Obrigado mesmo assim!
javascript
decrement
prefix-operator
not-operator
Kieran E
fonte
fonte
!~--[value] ^ true
Eu código de chamada como esta "segurança no emprego"-->
operador?Respostas:
!
inverte um valor e fornece o booleano oposto:--[value]
subtrai um (1) de um número e, em seguida, retorna esse número a ser trabalhado:Portanto,
!--pending
subtrai um de pendente e retorna o oposto de seu valor de verdade / falsidade (seja ou não0
).E sim, siga a ProTip. Esse pode ser um idioma comum em outras linguagens de programação, mas para a maior parte da programação declarativa de JavaScript isso parece bastante estranho.
fonte
--
atua apenas em variáveis; você não pode aplicá-lo aos valores em geral.validSimpleAssignmentTarget
s, para ser exato. Isso inclui referências de identificador e referências de propriedade.--0
e--1
não vai funcionar. Literais numéricos não são válidos expressão do lado esquerdoi > -1
coisa do quei--
(e você esqueceui = init() - 1
). É para isso que servem os idiomas ... e todo programador deve aprendê-los.Não é um operador especial, são dois operadores padrão, um após o outro:
--
)!
)Isso faz
pending
com que seja diminuído e testado para ver se é zero.fonte
if(pending === 1)
?if( pending === 1 ) { done... } else { pending = pending - 1; }
.Várias respostas descrevem o que esse comando faz, mas não o porquê de ser feito dessa maneira aqui.
Eu venho do mundo C e leio
!--pending
como "faça uma contagem regressivapending
e verifique se é zero" sem realmente pensar nisso. É um idioma que eu acho que os programadores em linguagens semelhantes deveriam conhecer.A função usa
readdir
para obter uma lista de arquivos e subdiretórios, que eu chamarei coletivamente de "entradas".A variável
pending
monitora quantos deles ainda precisam ser processados. Começa como o comprimento da lista e conta para baixo em direção a zero à medida que cada entrada é processada.Essas entradas podem ser processadas fora de ordem, e é por isso que é necessário fazer uma contagem regressiva em vez de apenas usar um loop simples. Quando todas as entradas foram processadas, o retorno de chamada
done
é chamado para notificar o chamador original desse fato.Na primeira chamada, o to
done
é anexadoreturn
, não porque queremos retornar um valor, mas simplesmente para fazer com que a função pare de ser executada nesse ponto. Teria sido um código mais limpo descartar oreturn
e colocar a alternativa em umelse
.fonte
!--pending
falhará em muitos linters e diretrizes de estilo. É o suficiente para eu dizer que provavelmente não é idiomático (independentemente de a alternativa ser "melhor").int
parabool
implicitamente, e não tem absolutamente nada a ver com o uso de!--
.É uma taquigrafia.
!
não é".--
diminui um valor.Portanto,
!--
verifica se o valor obtido ao negar o resultado da diminuição de um valor é falso.Tente o seguinte:
O primeiro é falso, já que o valor de x é 1, o segundo é verdadeiro, pois o valor de x é 0.
Nota lateral:
!x--
verificaria primeiro se x é falso e depois o diminuiria.fonte
!
, enquanto a pré-correção tem precedência mais baixa. Precedência do operador JavaScriptvar x = 2; console.log(!x--); console.log(!x--); console.log(!x--);
). Embora o pós-reparo--
possa ser executado primeiro, seu valor de retorno é o valor da variável antes de decrementar ( Decrement Opperator ).!--
retorna a negação do resultado da diminuição de um valor". Somente código externo, comoconsole.log()
, verifica se seu conteúdo é verdadeiro.!
é o operador JavaScript NOT--
é um operador de pré-decremento. Assim,fonte
--
operador poderia trabalhar com uma constante ... talvez você quis dizer em--x
vez de--0
?significa
significa
fonte
if(0 == pending)
por causa do potencial de erros de digitação.if(0 = pending)
é um erro de sintaxe.if(pending = 0)
é uma atribuição que causará um comportamento confuso no código finalizado.if(0 = pending)
não é um erro de sintaxe - ele analisa bem -, mas um Erro de referência porque0
não é atribuível (ref ECMA-262 (6a ed), seção 12.14.1).É o operador not seguido pelo pré-decrementador no local.
Então, se
pending
era um número inteiro com um valor de 1:fonte
Apenas diminui
pending
em um e obtém seu complemento lógico (negação). O complemento lógico de qualquer número diferente de 0 éfalse
, para 0 étrue
.fonte
Explicação
São 2 operadores, um
!
e um--
Portanto,
--
diminui x por 1, então!
retorna true se x agora é 0 (ou NaN ...), false se não for. Você pode ler esse idioma algo como "decrementamos xe se isso o torna zero ..."Se você quiser torná-lo mais legível, você pode:
Experimente:
Fiddle (código de teste)
fonte
O verdadeiro problema aqui é a falta de espaço entre os dois operadores
!
e--
.Não sei por que as pessoas pensam que você nunca pode usar um espaço depois do
!
operador. Eu acho que vem da aplicação rígida de regras de espaços em branco mecânicos em vez do senso comum. Praticamente todos os padrões de codificação que eu vi proíbem os espaços depois de todos os operadores unários, mas por quê?Se houve um caso em que você claramente precisa desse espaço, esse é um.
Considere este pedaço de código:
Não são apenas
!
e--
misturados, você tem que(
bater contra eles também. Não é de admirar que seja difícil dizer o que está conectado ao que.Um pouco mais de espaço em branco torna o código muito mais claro:
Claro, se você está acostumado a regras mecânicas como "sem espaço dentro de parênteses" e "sem espaço após um operador unário", isso pode parecer um pouco estranho.
Mas observe como o espaço em branco extra agrupa e separa as várias partes da
if
declaração e da expressão: você tem--pending
, portanto esse--
é claramente o seu próprio operador e está intimamente ligadopending
. (Ele decrementapending
e retorna o resultado decrementado.) Depois, você!
separa isso e, portanto, é obviamente um operador distinto, negando o resultado. Finalmente, você temif(
e)
envolve toda a expressão para torná-la umaif
declaração.E sim, removi o espaço entre
if
e(
, porque(
pertence ao arquivoif
. Isso(
não faz parte de algum tipo de(!--
sintaxe, como parece estar no original, a(
parte if da sintaxe daif
própria declaração.O espaço em branco aqui serve para comunicar o significado , em vez de seguir algum padrão de codificação mecânica.
fonte
!--
ser um operador javascript que eu não conhecia. Por que não usar parênteses para torná-lo ainda mais explícito?if(!(--pending))
++
ou--
, mas muitos não proibir utilização de espaços não-essenciais, como após o!
operador de prefixo e parênteses não essenciais.