Выполнить javascript синхронно в ячейке Jupyter Notebook - PullRequest
2 голосов
/ 31 января 2020

В блокноте Jupyter мы можем выполнять ячейки Javascript / HTML непосредственно для обогащения экрана ноутбука, например интерактивного графика Vis.js, благодаря следующему import:

from IPython.display import Javascript
from IPython.core.display import display, HTML

I иметь следующие ячейки Notebook:

  • Ячейка 1: зарегистрировать служебную функцию, чтобы впоследствии ее можно было вызывать несколько раз.
%%javascript
requirejs.config({
    paths: {
        vis: 'vis'
    }
});

require(['vis'], function(vis){
    function drawNetworkGraph() {
    ...
    }
    window.drawNetworkGraph = drawNetworkGraph;
});
  • Ячейка 2: Попробуйте вызвать служебную функцию.
transfer_data_from_python_to_javascript = "..."
display(Javascript(transfer_data_from_python_to_javascript))
display(Javascript("""window.drawNetworkGraph();""")) // <-- problem here!

При выполнении «Выполнить все» в блокноте я получил условие гонки, где window.drawNetworkGraph is not a function в консоли DevTools.

Это связано с чтобы require(, function(){}) в ячейке 1 работал асинхронно. Браузеру требуется некоторое время для загрузки библиотеки vis; и когда он завершит загрузку, он вызовет функцию, объявленную во втором аргументе require(). На данный момент Блокнот Jupyter уже выполняет Cell 2, что приводит к not a function.

Вопрос

В мире Javascript настоятельно рекомендуется писать код асинхронно. Вот почему require() поддерживает обратный вызов. Какова лучшая практика для преодоления такой настройки в Jupyter Notebook?

Моя цель - внедрить vis.js график. Не стесняйтесь предложить что-нибудь. Спасибо.

Мои попытки

1). Удалите ячейку 1. В ячейке 2 или аналогичной ячейке всякий раз, когда вы хотите вызвать такую ​​функцию полезности, мы заключаем все javascript в ячейку 1. Недостаток: громоздкий, потому что у нас есть много других последних ячеек, которые вызывают функцию полезности.

2). Используйте механизм ожидания в javascript: проверьте, определено ли window.drawGraphNetwork или нет; если есть, позвоните; если нет, setTimeOut, чтобы назвать это немного позже. Недостаток: немного сложнее.

Тем не менее, эти подходы менее элегантны.

...