В блокноте 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
, чтобы назвать это немного позже. Недостаток: немного сложнее.
Тем не менее, эти подходы менее элегантны.