次の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
の2つのフィールドがあります。 .next
は、リストの次のノードに解決される約束です。
毎回addData(...)
が呼び出されると、リストの現在の最後のノードの.next
フィールドが新しいノードに解決され、新しい最後のノードになります。
上記のコードの機能を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