Имеет ли следующий код javascript неопределенное поведение?
var resolve;
var head = { next: new Promise(r => resolve = r) };
function addData(d) {
resolve({
data: d,
next: new Promise(r => resolve = r)
});
}
Я написал код выше, чтобы достичь чего-то похожее на связанный список, в то время как данные в списке загружаются асинхронно.
Руководитель этого «связанного списка» - head
. Каждый узел в списке имеет два поля: .data
и .next
, как обычный связанный список. .next
- это обещание, которое будет разрешено для следующего узла в списке.
Каждый раз, когда вызывается addData(...)
, поле текущего последнего узла в списке разрешает новый узел и, таким образом, становится новым последним узлом.
Я проверил функциональность вышеуказанного кода в Node.js и работает как ожидалось. Вот код, я использую, чтобы проверить поведение:
var resolve;
var head = { next: new Promise(r => resolve = r) };
function addData(d) { resolve({ data: d, next: new Promise(r => resolve = r) }); }
async function verify() {
while(true) {
head = await head.next;
console.log(head.data);
}
}
verify();
addData(1); // outputs: 1
addData(2); // outputs: 2
addData(3); // outputs: 3
Однако, я не уверен, есть ли потенциальная проблема (память, КПД) с этой структурой. Кроме того, я особенно обеспокоен этой линии:
resolve({data: d, next: new Promise(r => resolve = r})
где решительность называется и назначается одновременно. Что должно произойти сперва, назначение или разрешение имени функции? Является ли это неопределенным поведением?
Спасибо!
Независимо от того, работает оно или нет, он уверен, что он тупой (трудно читать и понимать точку кода). – jfriend00
@ jfriend00 Он сохранил всю цепочку, если бы сохранил ссылку на начальную голову, которую он не делает. Конечно, легко ошибиться ... – Bergi
@Bergi - Я уже удалил этот комментарий, потому что я пришел к выводу, что это слишком сложно понять, что происходит (по моему мнению, это плохой код). Но OP действительно сказал «как связанный список», но я думаю, что это вообще не связанный список. Я предполагаю, что это только более высокий охват кэша предыдущего обещания. Разве нет намного лучшего способа сделать это, что не так тупо и не использует переменную 'resolve' с более высоким охватом? – jfriend00