Вы вызываете функцию немедленно, а не вызываете ее в рамках обратного вызова setTimeout
.
function sayLetter(n)
{
if (n > 0)
{
console.log(n)
setTimeout(() => {
sayLetter(n-1)
}, 1000);
}
}
sayLetter(3);
В Oracle:
SELECT LEVEL, Id, Name, LPAD(' ', LEVEL) || Name AS IndentedName
FROM Categories
START WITH
ParentID IS NULL
CONNECT BY
ParentID = PRIOR Id
ORDER SIBLINGS BY
Name
Можно использовать IndentedName
или сделайте Вас пользовательским форматированием на основе LEVEL
псевдостолбец (это показывает глубину каждой категории),
P.S. это - a bad
идея использовать NULL
как главный родительский идентификатор, поскольку Вы не можете использовать индекс для доступа к нему. Используйте a 0
вместо этого.
Обновление:
В SQL Server
:
WITH q (id, parentid, name, level, bc) AS
(
SELECT id, parentid, name, 1, CAST(ROW_NUMBER() OVER (ORDER BY name) AS VARCHAR(MAX))
FROM Categories
WHERE ParentID IS NULL
UNION ALL
SELECT c.id, c.parentid, c.name, q.level + 1, q.bc + '.' + CAST(ROW_NUMBER() OVER (ORDER BY c.name) AS VARCHAR(MAX))
FROM q
JOIN Categories c
ON c.parentId = q.id
)
SELECT *
FROM q
ORDER BY
bc
В отличие от этого, Oracle
, SQL Server
индексы NULL
значения, таким образом, возможно использовать a NULL
отметить окончательного предка.
SQL Server имеет иерархический тип данных. Не пользовался, но смотрится интересно. http://msdn.microsoft.com/en-us/magazine/cc794278.aspx .
То, что я часто использую в таких ситуациях, - это дерево слева направо. Они эффективны для запроса данных. Самое главное, у меня есть определенный слой для загрузки и сохранения моего дерева. Это захватит всех дочерних элементов из базы данных и загрузит дерево в память. Слой также будет отвечать за перемещение узлов в дереве, удаление узлов и т. Д. Если у вас есть дерево, организованное в памяти, вы можете делать все оттуда. Надеюсь, что это поможет, дайте мне знать, если вам нужны образцы кода общего левого / правого дерева.