Интересно, может ли следующий код привести к тому, что целое число i
в объекте context
будет иметь недопустимое значение. До сих пор я не мог вызвать проблемы в своих экспериментах.
// Node.js (v10.19.0)
const Promise = require('promise')
// object accessed from different async processes in parallel
let context = {i: 0}
// create async functions
let funkMaker = function(i) {
return async function(context) {
context.i += 1;
console.log(`Funk${i} at ${Date.now()}: Incremented argument 'context.i' to: ${context.i}`);
return context.i
}
}
// create async processes
let funksArr = [];
for (k=1; k<101; k++) {
funksArr.push(funkMaker(k))
}
// invoke async processes in parallel
Promise.all(
funksArr.map(f => f(context))
).then(
x => console.log(`Promise.all resolved with ${x}`)
).catch(
e => console.log(`Promise.all raised an error:\n${e}`)
)
Выше приведен следующий вывод (отрывок):
Funk1 at 1584448782621: Incremented argument 'context.i' to: 1
Funk2 at 1584448782621: Incremented argument 'context.i' to: 2
Funk3 at 1584448782622: Incremented argument 'context.i' to: 3
Funk4 at 1584448782622: Incremented argument 'context.i' to: 4
Funk5 at 1584448782622: Incremented argument 'context.i' to: 5
Funk6 at 1584448782622: Incremented argument 'context.i' to: 6
Funk7 at 1584448782622: Incremented argument 'context.i' to: 7
Funk8 at 1584448782622: Incremented argument 'context.i' to: 8
Funk9 at 1584448782622: Incremented argument 'context.i' to: 9
Как вы можете видеть, есть несколько процессов, которые похоже, что он обращается к context.i
в ту же миллисекунду (Funk3
до Funk9
выше). Я озадачен тем, почему целое число context.i
все еще увеличивается правильно и без ошибок.
Выводы приветствуются. Спасибо!
ОБНОВЛЕНИЕ
Чтобы попробовать это в реальных системных темах, я исправил код, украденный из этого сообщения в блоге , который использует crypto
и неявно libuv
для выполнения в реальных потоках. Я все еще не мог заставить мой context.i
сломаться. И я все еще озадачен, если честно.
const crypto = require("crypto");
const start = Date.now();
let context = {i: 0}
function logHashTime(context) {
crypto.pbkdf2("a", "b", 100000, 512, "sha512", () => {
context.i += 1;
console.log(`Hash: ${Date.now() - start}, 'context.i' incremented to: ${context.i}`);
});
}
for (i = 0; i < 100; i++) {
logHashTime(context)
}
Вывод (выдержка) все еще "в порядке":
Hash: 1268, 'context.i' incremented to: 1
Hash: 1460, 'context.i' incremented to: 2
Hash: 1660, 'context.i' incremented to: 3
Hash: 1907, 'context.i' incremented to: 4
Hash: 2493, 'context.i' incremented to: 5
Hash: 2673, 'context.i' incremented to: 6
Hash: 3154, 'context.i' incremented to: 7
Hash: 3215, 'context.i' incremented to: 8
Hash: 3662, 'context.i' incremented to: 9