Могут ли две асинхронные задачи обращаться к одному и тому же массиву одновременно? - PullRequest
0 голосов
/ 02 сентября 2018

Предположим, у вас есть массив, который изменяется одним асинхронным процессом, а затем у вас есть другой асинхронный процесс, который читает из того же массива. Модификации и чтения выполняются синхронно. Теперь возникает вопрос: может ли процесс чтения каким-то образом получить доступ к массиву, когда он изменяется процессом записи?

Из своего опыта я знаю, что он не может и во время выполнения синхронных операций поток и, следовательно, все ресурсы (включая массив), с которыми он работает, будут заблокированы. Правильно? Но является ли это логическим следствием того факта, что JavaScript является однопоточным, или он определен где-то конкретно в спецификации?

Ответы [ 2 ]

0 голосов
/ 02 сентября 2018

Один из подходов, который я хотел бы сделать, - создать 3 массива.

 let kingArray = [];
 let arrayForProcess1 = [];
 let arrayForProcess2 = [];

 someProcessOneExecution().then(response => {
    if (kingArray.length === 0) {
       arrayForProcess1 = response;
    } else {
       doSomethingWithResponse(response);
    }
 });

 someProcessTwoExecution().then(response => {
    if (kingArray.length === 0) {
       arrayForProcess2 = response;
    } else {
       doSomethingWithResponse(response);
    }
 });

 function doSomethingWithResponse() {
    // so something here..
 }

Это не совсем то, что вы просили, но цикл событий javascript или стек вызовов будут выполнять их один за другим. Так как JS является однопоточным. Он будет ожидать разрешения этих обещаний, поскольку они являются базами ввода-вывода и по мере их разрешения. может быть process1 или process2. Вы можете проверить их вручную, как в подходе выше, который не самый оптимальный.

Второй подход

В этом случае я хотел бы объединить эти два обещания и подождать, пока они будут решены одно за другим, и соответствующим образом обновить мой массив.

Мое личное мнение (мнение в 2 цента). Я бы никогда не попытался обновить один и тот же массив в одно и то же время, если в этом сценарии он используется, может быть, стратегию выполнения проблемы нужно переосмыслить снова.

0 голосов
/ 02 сентября 2018

Теперь вопрос в том, может ли процесс чтения каким-либо образом получить доступ к массиву во время его изменения процессом записи?

Нет, JavaScript является однопоточным. Единственный способ одновременного доступа к одним и тем же данным через JS - это использовать несколько общих ресурсов между двумя разными JS-скриптами. В сети, которая может быть WebWorkers с SharedArrayBuffers, в Nodejs некоторые базы данных допускают одновременные мутации.

Но логически ли это вытекает из того факта, что JavaScript является однопоточным или он определен где-то в спецификации?

Спецификации определяют потоки, называемые агентами:

8,3 Агенты

Агент содержит набор контекстов исполнения ECMAScript, стек контекста исполнения, контекст работающего выполнения, набор именованных очередей заданий, запись агента и поток выполнения. За исключением исполняющего потока, составляющие агент принадлежит исключительно этому агенту .

Это означает, что весь код выполняется в одном потоке (очередь заданий), все переменные доступны только из одного потока (контекст выполнения). Единственный способ разделить память между разными агентами (потоками) - это использовать SharedArrayBuffer, и вам нужны разные агенты (например, веб-работники).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...