Так что я предполагаю, что мой вопрос, когда обещание разрешится, будет ли немедленно запущен блок кода .then, который запускает addObjectToWorld, или другой код потенциально будет запущен первым (например, другой игрок также найдет область свободной)
Посмотрите этот пример:
'use strict';
async function work(i) {
const interval = setInterval(() => { console.log('interval', i); }, 1);
setImmediate(() => console.log('immediate', i));
process.nextTick(() => console.log('nexttick', i));
await findEmptyArea(i);
addObjectToWorld(i, interval);
}
function addObjectToWorld(k, interval) {
console.log('add object to the world', k);
clearInterval(interval);
}
function findEmptyArea(k) {
console.log('findEmptyArea resolving', k);
return new Promise((resolve, reject) => {
console.log('findEmptyArea executing', k);
for (let i = 0; i < 1000000000; i++) {
// high computation
}
resolve({ success: true, x: 1, y: 1 });
});
}
for (let x = 0; x < 10; x++) {
work(x);
}
nextTick
запускается до addObjectToWorld
.
Возможно ли, что цикл событий nodejs разрешит что-то еще запускаться первым?
Если посмотреть на пример, если у вас нет асинхронного кода (I / O), все будет последовательно в зависимости от цикла событий.
Я включил это в обещание, так как playerJoin будет часто запускаться при подключении новых игроков, и я не хочу, чтобы он блокировался.
Учтите, что добавление Promise
или async
не преобразует ваш код в неблокирование цикла событий: вы все еще блокируете цикл событий также с помощью обещаний (проверьте for < 1000000000
: он блокирует цикл обработки событий для всех подключающихся пользователей.
Чтобы не блокировать цикл обработки событий, вы должны запустить задачу с высокими вычислениями в технологическом процессе или дочернем процессе.
Если вам это нравится, ваш цикл обработки событий не остановится, поэтому вы сможете обслуживать больше пользователей и расширять их при необходимости.
Но, конечно, в этом случае вы должны внедрить шаблон блокировки, например оптимистический , чтобы зарезервировать свободное место.
* +1034 * Пример: * * одна тысяча тридцать пять
'use strict';
const { Worker } = require('worker_threads');
async function work(i) {
const interval = setInterval(() => { console.log('interval', i); }, 1);
setImmediate(() => console.log('immediate', i));
process.nextTick(() => console.log('nexttick', i));
await findEmptyArea(i);
addObjectToWorld(i, interval);
}
function addObjectToWorld(k, interval) {
console.log('add object to the world', k);
clearInterval(interval);
}
function findEmptyArea(k) {
console.log('findEmptyArea resolving', k);
return new Promise((resolve, reject) => {
const worker = new Worker('./worker.js', { workerData: k });
worker.on('message', resolve);
worker.on('error', reject);
worker.on('exit', (code) => {
if (code !== 0) reject(new Error(`Worker stopped with exit code ${code}`));
});
});
}
for (let x = 0; x < 10; x++) {
work(x);
}
// worker.js
'use strict';
const { workerData, parentPort } = require('worker_threads');
console.log('findEmptyArea executing', workerData);
for (let i = 0; i < 1000000000; i++) {
// high computation
}
parentPort.postMessage({ hello: workerData });