diff options
Diffstat (limited to 'files/ru/webassembly/loading_and_running/index.html')
-rw-r--r-- | files/ru/webassembly/loading_and_running/index.html | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/files/ru/webassembly/loading_and_running/index.html b/files/ru/webassembly/loading_and_running/index.html new file mode 100644 index 0000000000..a796cc7a30 --- /dev/null +++ b/files/ru/webassembly/loading_and_running/index.html @@ -0,0 +1,114 @@ +--- +title: Загрузка и запуск кода WebAssembly +slug: WebAssembly/Loading_and_running +tags: + - Fetch + - JavaScript + - WebAssembly + - XMLHttpRequest + - bytecode +translation_of: WebAssembly/Loading_and_running +--- +<div>{{WebAssemblySidebar}}</div> + +<p class="summary">Чтобы использовать WebAssembly в JavaScript, сначала нужно загрузить модуль в память перед компиляцией/созданием экземпляра. Эта статья содержит справочную информацию о различных механизмах, которые можно использовать для получения байт-кода WebAssembly, а также о том, как скомпилировать/создать экземпляр, а затем запустить его.</p> + +<h2 id="Какие_есть_варианты">Какие есть варианты?</h2> + +<p><span class="tlid-translation translation" lang="ru"><span title="">WebAssembly еще не интегрирована с </span></span> <code><script type='module'></code> <span class="tlid-translation translation" lang="ru"><span title="">или ES2015 </span><span class="alt-edited" title="">оператором</span></span> <code>import</code>, <span class="tlid-translation translation" lang="ru"><span title="">поэтому не существует пути, позволяющего использовать модули загрузки браузера для использования импорта.</span></span></p> + +<p><span class="tlid-translation translation" lang="ru"><span title="">Старые методы</span></span> {{jsxref("WebAssembly.compile")}}/{{jsxref("WebAssembly.instantiate")}} <span class="tlid-translation translation" lang="ru"><span title="">требуют создания </span></span>{{domxref("ArrayBuffer")}}, <span class="tlid-translation translation" lang="ru"><span title="">содержащего двоичный файл модуля WebAssembly после загрузки необработанных байтов, а затем скомпилировать/создать его экземпляр.</span></span> <span class="tlid-translation translation" lang="ru"><span title="">Это аналог</span></span> <code>new Function(string)</code>,<span class="tlid-translation translation" lang="ru"><span title=""> за исключением того, что мы заменяем строку символов (исходный код JavaScript) буфером байтов массива (исходный код WebAssembly).</span></span></p> + +<p><span class="tlid-translation translation" lang="ru"><span title="">Более новые методы </span></span>{{jsxref("WebAssembly.compileStreaming")}}/{{jsxref("WebAssembly.instantiateStreaming")}} <span class="tlid-translation translation" lang="ru"><span title="">намного эффективнее - они выполняют свои действия непосредственно с необработанным потоком байтов, поступающих из сети,</span> <span title="">избавление от необходимости шага </span></span>{{domxref("ArrayBuffer")}}.</p> + +<p>Итак, как мы можем получить эти байты в буфер массива и скомпилировать? Следующие разделы объясняют.</p> + +<h2 id="Используя_Fetch">Используя Fetch</h2> + +<p><a href="/en-US/docs/Web/API/Fetch_API">Fetch</a><span class="tlid-translation translation" lang="ru"><span title=""> - это удобный современный API для извлечения сетевых ресурсов.</span></span></p> + +<p><span class="tlid-translation translation" lang="ru"><span title="">Самый быстрый и эффективный способ получить модуль wasm - использовать более новый метод </span></span>{{jsxref("WebAssembly.instantiateStreaming()")}}, <span class="tlid-translation translation" lang="ru"><span title="">который может принять вызов </span></span><code>fetch()</code> <span class="tlid-translation translation" lang="ru"><span title="">в качестве первого аргумента и будет обрабатывать загрузку, компиляцию</span> <span title="">и создание экземпляра модуля за один шаг, получая доступ к необработанному байтовому коду при его потоковой передаче с сервера:</span></span></p> + +<pre class="brush: js">WebAssembly.instantiateStreaming(fetch('simple.wasm'), importObject) +.then(results => { + // Do something with the results! +});</pre> + +<p><span class="tlid-translation translation" lang="ru"><span title="">Если бы мы использовали более старый метод</span></span> {{jsxref("WebAssembly.instantiate()")}}, <span class="tlid-translation translation" lang="ru"><span title="">который не работает в прямом потоке, нам потребовался бы дополнительный шаг преобразования преобразованного байт-кода в </span></span>{{domxref("ArrayBuffer")}}, <span class="tlid-translation translation" lang="ru"><span title="">вот так:</span></span></p> + +<pre class="brush: js">fetch('module.wasm').then(response => + response.arrayBuffer() +).then(bytes => + WebAssembly.instantiate(bytes, importObject) +).then(results => { + // Do something with the results! +});</pre> + +<p> </p> + +<h3 id="Помимо_перегрузок_instantiate()"><span class="tlid-translation translation" lang="ru"><span title="">Помимо перегрузок instantiate()</span></span></h3> + +<p><span class="tlid-translation translation" lang="ru"><span title="">Функция</span></span> {{jsxref("WebAssembly.instantiate()")}}<span class="tlid-translation translation" lang="ru"><span title=""> имеет две формы перегрузки - та, что показана выше, принимает байт-код для компиляции в качестве аргумента и возвращает </span></span><code>Promise</code><span class="tlid-translation translation" lang="ru"><span title="">, которое разрешается для объекта, содержащего оба объекта скомпилированного модуля,</span> <span title="">и экземпляр этого.</span> <span title="">Объект выглядит так:</span></span></p> + +<pre class="brush: js">{ + module : Module // The newly compiled WebAssembly.Module object, + instance : Instance // A new WebAssembly.Instance of the module object +}</pre> + +<div class="note"> +<p><strong>Примечание</strong>: <span class="tlid-translation translation" lang="ru"><span title="">Обычно мы заботимся только об экземпляре, но полезно иметь модуль на тот случай, если мы хотим его кешировать, поделиться им с другим работником или окном через</span></span> <code><a href="/en-US/docs/Web/API/MessagePort/postMessage">postMessage()</a></code>, <span class="tlid-translation translation" lang="ru"><span title="">или просто создать больше экземпляров.</span></span></p> +</div> + +<div class="note"> +<p><strong>Примечание</strong>: <span class="tlid-translation translation" lang="ru"><span title="">Вторая форма перегрузки принимает в качестве аргумента объект </span></span>{{jsxref("WebAssembly.Module")}} <span class="tlid-translation translation" lang="ru"><span title="">и возвращает </span></span><code>Promise</code><span class="tlid-translation translation" lang="ru"><span title="">, непосредственно содержащее объект экземпляра, в качестве результата.</span> <span title="">См. <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiate#Second_overload_example">Второй пример перегрузки</a>.</span></span></p> +</div> + +<h3 id="Выполнение_вашего_кода_WebAssembly">Выполнение вашего кода WebAssembly</h3> + +<p><span class="tlid-translation translation" lang="ru"><span title="">Когда у вас есть экземпляр WebAssembly, доступный в вашем JavaScript, вы можете начать использовать его возможности, которые были экспортированы через свойство </span></span>{{jsxref("WebAssembly.Instance/exports", "WebAssembly.Instance.exports")}}. <span class="tlid-translation translation" lang="ru"><span title="">Ваш код может выглядеть примерно так:</span></span></p> + +<pre class="brush: js">WebAssembly.instantiateStreaming(fetch('myModule.wasm'), importObject) +.then(obj => { + // Call an exported function: + obj.instance.exports.exported_func(); + + // or access the buffer contents of an exported memory: + var i32 = new Uint32Array(obj.instance.exports.memory.buffer); + + // or access the elements of an exported table: + var table = obj.instance.exports.table; + console.log(table.get(0)()); +})</pre> + +<div class="note"> +<p><strong>Примечание</strong>: <span class="tlid-translation translation" lang="ru"><span title="">Для получения дополнительной информации о том, как работает экспорт из модуля WebAssembly, ознакомьтесь с разделами</span></span> <a href="/en-US/docs/WebAssembly/Using_the_JavaScript_API">Использование JavaScript API WebAssembly</a>, и <a href="/en-US/docs/WebAssembly/Understanding_the_text_format">Понимание текстового формата WebAssembly</a>.</p> +</div> + +<h2 id="Используя_XMLHttpRequest">Используя XMLHttpRequest</h2> + +<p><code><a href="/en-US/docs/Web/API/XMLHttpRequest">XMLHttpRequest</a></code> <span class="tlid-translation translation" lang="ru"><span title="">несколько старше, чем</span></span> Fetch, <span class="tlid-translation translation" lang="ru"><span title="">но все же может успешно использоваться для получения типизированного массива.</span> <span title="">Опять же, если предположить, что наш модуль называется </span></span><code>simple.wasm</code>:</p> + +<ol> + <li><span class="tlid-translation translation" lang="ru"><span title="">Создайте новый экземпляр </span></span>{{domxref("XMLHttpRequest()")}} <span class="tlid-translation translation" lang="ru"><span title="">и используйте его метод </span></span>{{domxref("XMLHttpRequest.open","open()")}} <span class="tlid-translation translation" lang="ru"><span title="">для открытия запроса, задав для метода запроса значение </span></span> <code>GET</code> <span class="tlid-translation translation" lang="ru"><span title="">и указав путь к файлу, который мы хотим получить.</span></span></li> + <li><span class="tlid-translation translation" lang="ru"><span title="">Ключевой частью этого является установка типа ответа </span></span> <code>'arraybuffer'</code> <span class="tlid-translation translation" lang="ru"><span title="">с помощью свойства </span></span>{{domxref("XMLHttpRequest.responseType","responseType")}}.</li> + <li><span class="tlid-translation translation" lang="ru"><span title="">Затем отправьте запрос с помощью </span></span>{{domxref("XMLHttpRequest.send()")}}.</li> + <li><span class="tlid-translation translation" lang="ru"><span title="">Затем мы используем обработчик событий </span></span>{{domxref("XMLHttpRequest.onload", "onload")}} <span class="tlid-translation translation" lang="ru"><span title="">для вызова функции после завершения загрузки ответа - в этой функции мы получаем буфер массива из</span></span> {{domxref("XMLHttpRequest.response", "response")}} <span class="tlid-translation translation" lang="ru"><span title="">и затем передайте это в наш метод</span></span> {{jsxref("WebAssembly.instantiate()")}}, <span class="tlid-translation translation" lang="ru"><span title="">как мы это делали с Fetch.</span></span></li> +</ol> + +<p>Финальный код выглядит так:</p> + +<pre class="brush: js">request = new XMLHttpRequest(); +request.open('GET', 'simple.wasm'); +request.responseType = 'arraybuffer'; +request.send(); + +request.onload = function() { + var bytes = request.response; + WebAssembly.instantiate(bytes, importObject).then(results => { + results.instance.exports.exported_func(); + }); +};</pre> + +<div class="note"> +<p><strong>Примечание</strong>: Вы можете увидеть пример этого в действии в <a href="https://mdn.github.io/webassembly-examples/js-api-examples/xhr-wasm.html">xhr-wasm.html</a>.</p> +</div> |