Tengo este código (tomado de esta pregunta ):
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);
}
});
});
});
};
Estoy tratando de seguirlo, y creo que entiendo todo, excepto cerca del final donde dice !--pending
. En este contexto, ¿qué hace ese comando?
Editar: agradezco todos los comentarios adicionales, pero la pregunta ha sido respondida muchas veces. ¡Gracias de cualquier manera!
javascript
decrement
prefix-operator
not-operator
Kieran E
fuente
fuente
!~--[value] ^ true
Llamo a un código como este "seguridad laboral"-->
operador?Respuestas:
!
invierte un valor y le da el booleano opuesto:--[value]
resta uno (1) de un número y luego devuelve ese número para trabajarlo:Entonces,
!--pending
resta uno de pendiente y luego devuelve lo opuesto a su valor de verdad / falsedad (ya sea que sea o no0
).Y sí, sigue la ProTip. Esto puede ser un idioma común en otros lenguajes de programación, pero para la mayoría de la programación declarativa de JavaScript esto parece bastante extraño.
fuente
--
actúa solo en variables; No se puede aplicar a los valores en general.validSimpleAssignmentTarget
s, para ser exactos. Eso incluye referencias de identificador y referencias de propiedad.--0
y--1
no funcionará Los literales numéricos no son expresiones válidas del lado izquierdoi > -1
cosa quei--
(y por cierto lo olvidastei = init() - 1
). Para eso están los modismos ... y cada programador debería aprenderlos.Ese no es un operador especial, son 2 operadores estándar uno tras otro:
--
)!
)Esto hace
pending
que se disminuya y luego se pruebe para ver si es cero.fuente
if(pending === 1)
?if( pending === 1 ) { done... } else { pending = pending - 1; }
.Varias respuestas describen lo que hace este comando, pero no por qué se hace así aquí.
Vengo del mundo C, y leo
!--pending
como "cuenta atráspending
y verifica si es cero" sin pensar realmente en ello. Es un idioma que creo que los programadores en lenguajes similares deberían saber.La función se utiliza
readdir
para obtener una lista de archivos y subdirectorios, que colectivamente llamaré "entradas".La variable
pending
realiza un seguimiento de cuántos de estos quedan por procesar. Comienza como la longitud de la lista y cuenta hacia abajo hacia cero a medida que se procesa cada entrada.Estas entradas pueden procesarse fuera de servicio, por lo que es necesario realizar una cuenta regresiva en lugar de simplemente usar un bucle simple. Cuando se han procesado todas las entradas,
done
se llama a la devolución de llamada para notificar al llamador original de este hecho.En la primera llamada a
done
se anteponereturn
, no porque queramos devolver un valor, sino simplemente para que la función deje de ejecutarse en ese punto. Hubiera sido un código más limpio descartarreturn
y poner la alternativa en unelse
.fuente
!--pending
fallará muchas linters y pautas de estilo. Eso es suficiente para decir que probablemente no sea idiomático (independientemente de si la alternativa es "mejor").int
a labool
forma implícita, y no tiene absolutamente nada que ver con el uso de!--
.Es una taquigrafía.
!
no es".--
disminuye un valor.Por lo tanto,
!--
comprueba si el valor obtenido al negar el resultado de disminuir un valor es falso.Prueba esto:
El primero es falso, ya que el valor de x es 1, el segundo es verdadero, ya que el valor de x es 0.
Nota al margen:
!x--
primero verificaría si x es falso y luego lo disminuiría.fuente
!
, mientras que la corrección previa tiene menor prioridad. Precedencia del operador de JavaScriptvar x = 2; console.log(!x--); console.log(!x--); console.log(!x--);
) Si bien la corrección posterior--
puede ejecutarse primero, su valor de retorno es el valor de la variable antes de disminuir ( Operador de decremento ).!--
devuelve la negación del resultado de decrementar un valor". Solo el código externo, como por ejemploconsole.log()
, verifica si su contenido es verdadero.!
es el JavaScript NO operador--
es un operador de pre-decremento. Entonces,fuente
--
operador podría trabajar con una constante ... ¿quizás quiso decir en--x
lugar de--0
?medio
medio
fuente
if(0 == pending)
debido a la posibilidad de errores tipográficos.if(0 = pending)
es un error de sintaxisif(pending = 0)
es una tarea que causará un comportamiento confuso en el código terminado.if(0 = pending)
no es un error de sintaxis, se analiza bien, sino un error de referencia porque0
no es asignable (ref ECMA-262 (6ª ed) sec 12.14.1).Es el operador no seguido por el pre-decrementador en el lugar.
Entonces, si
pending
fuera un entero con un valor de 1:fuente
Simplemente disminuye
pending
en uno y obtiene su complemento lógico (negación). El complemento lógico de cualquier número diferente de 0 esfalse
, para 0 estrue
.fuente
Explicación
Esto es 2 operadores, a
!
y a--
Entonces, los
--
decrementos x por 1, entonces el!
devuelve verdadero si x es ahora 0 (o NaN ...), falso si no lo es. Puede leer este modismo algo así como "decrementamos xy si eso lo hace cero ..."Si desea que sea más legible, puede:
Pruébalo:
Fiddle (código de prueba)
fuente
El verdadero problema aquí es la falta de espacio entre los dos operadores
!
y--
.No sé por qué las personas piensan que no se puede usar un espacio después del
!
operador. Creo que proviene de la aplicación rígida de las reglas mecánicas de espacios en blanco en lugar del sentido común. Casi todos los estándares de codificación que he visto prohíben espacios después de todos los operadores unarios, pero ¿por qué?Si alguna vez hubo un caso en el que claramente necesita ese espacio, este es uno.
Considere este bit de código:
No solo son
!
y se--
mezclan, tienes eso(
golpeado contra ellos también. No es de extrañar que sea difícil saber qué está conectado a qué.Un poco más de espacio en blanco hace que el código sea mucho más claro:
Claro, si estás acostumbrado a las reglas mecánicas como "sin espacio dentro de parens" y "sin espacio después de un operador unario", esto puede parecer un poco extraño.
Pero observe cómo el espacio en blanco adicional agrupa y separa las diversas partes de la
if
declaración y la expresión: lo tiene--pending
, por lo--
que claramente es su propio operador y está estrechamente vinculadopending
. (Disminuyepending
y devuelve el resultado decrementado). Entonces tienes el!
separado de eso, por lo que obviamente es un operador distinto, que niega el resultado. Finalmente, tienesif(
y)
rodea toda la expresión para que sea unaif
declaración.Y sí, eliminé el espacio entre
if
y(
, porque(
pertenece alif
. Esto(
no es parte de algún tipo de(!--
sintaxis, ya que parece estar en el original,(
si es parte de la sintaxis de laif
declaración en sí.El espacio en blanco aquí sirve para comunicar el significado , en lugar de seguir algún estándar de codificación mecánica.
fuente
!--
era un operador de JavaScript que no conocía. ¿Por qué no usar paréntesis para hacerlo aún más explícito?if(!(--pending))
++
o--
, pero muchas sí prohíben el uso de espacios no esenciales, como después del!
operador de prefijo, y paréntesis no esenciales.