Возвращаемое значение из обратного вызова AMD

Я работаю с javascript API ArcGIS, который построен на require и определении асинхронного модуля. Чтобы создать карту, вы определяете все свои действия внутри обратного вызова инструкции AMD require:

require([
  "esri/Map", 
  "esri/views/MapView"
], function(Map, MapView){
   
  const map = new Map({ ... })
  const view = new MapView({ ... })
   
})

Я хотел бы иметь возможность инициализировать это поведение по команде из другого модуля, а также получить доступ к объектам map и view, которые определены в обратном вызове AMD. Чтобы иметь возможность инициализировать это по команде, я могу обернуть его функцией и экспортировать эту функцию:

export const makeMap = () => {

   require([esri modules], function(Map, MapView){
   
      map = new Map({ ... })
      view = new MapView({ ... })
   
   })

}

Я могу импортировать makeMap в какой-то другой модуль в моем коде и вызвать его. Это работает хорошо. Однако я пытаюсь выяснить, как я могу получить доступ к объектам map и view, чтобы иметь возможность манипулировать ими через пользовательский интерфейс. Сначала я попробовал это:

// mapMap.js
export const makeMap = () => {

   let mapInstance;
   let viewInstance;

   require([esri modules], function(Map, MapView){
   
      map = new Map({ ... })
      view = new MapView({ ... })

      mapInstance = map   
      viewInstance = view
   
   })

   return { mapInstance, viewInstance }

}

// some other module
import { makeMap } from './makeMap'

const { mapInstance, viewInstance } = makeMap()

Очевидно, это не работает — mapInstance и viewInstance не определены, поскольку функция, определяющая их внутри обратного вызова AMD, запускается после их возврата из вызова makeMap().

Я не уверен, как я могу получить возвращаемое значение из обратного вызова AMD. Это возможно? Нужна ли мне другая парадигма?

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

// maprefs.js
export const maprefs = {}

// makeMap.js
import { maprefs } from './maprefs'

export const makeMap = (maprefs, mapname) => {

   require([esri modules], function(Map, MapView){
   
      map = new Map({ ... })
      view = new MapView({ ... })

      maprefs[mapname] = { map, view }
   
   })

}

// some module
import { maprefs } from './maprefs'
import { makeMap } from './makeMap'

makeMap(maprefs, "map1")

someButton.addEventListener('click', () => {
  // maprefs.map1 is properly defined as { mapInstance, viewInstance } and I can take action on it
  maprefs.map1.doSomething
})

Я взглянул на Как мне вернуть ответ от асинхронный вызов?, который касается перенастройки значений из вызовов ajax, но я изо всех сил пытаюсь связать это с обратными вызовами AMD.

Можно ли вернуть значение из обратного вызова AMD для использования в другом месте? Я надеюсь на синтаксис типа const { map, value } = makeMap().


person Seth Lutske    schedule 08.09.2020    source источник


Ответы (1)


В упомянутом вами сценарии я думаю, что лучшим решением будет использование esri-loader. Это крошечная библиотека, созданная ESRI именно для этой цели, то есть для загрузки модулей библиотеки ArcGIS JS API во время выполнения.

Документы ArcGIS — esri-loader

Github ESRI — использование esri-загрузчика

person cabesuon    schedule 08.09.2020
comment
это довольно идеально, так как я планирую встроить все это в приложение для реагирования. Спасибо! - person Seth Lutske; 08.09.2020
comment
Рад, что вам помогает!! - person cabesuon; 08.09.2020