Почему элементы массива передаются в .then (), доступный по имени в Typescript? - PullRequest
0 голосов
/ 09 мая 2018

Я начал интегрировать наш шаблон ArcGis JS в используемый нами конвейер сборки веб-пакетов.

Чтобы выполнить это, нам нужно немного изменить рефакторинг и начать использовать Esri-Loader (https://github.com/Esri/esri-loader),, который по сути превращает dojos require function в обещание.

Действительно простой пример выглядит так:

start = () => {
    return EsriLoader.loadModules(['esri/Map', 'esri/views/MapView', "esri/Basemap"])
        .then(([Map, MapView, Basemap]) => {
            const map = new Map({
                basemap: "streets"
              });

              const view = new MapView({
                map: map,
                container: "map"
              });
        });
}

Сначала я попытался записать вызов .then() следующим образом: .then((Map, MapView, Basemap) => { ... }, но получал следующую ошибку компилятора:

Аргумент типа '(Map: any, MapView: any, Basemap: any) => void' is нельзя назначить параметру типа '(значение: любое []) => void | PromiseLike.

Хорошо, подпись не складывается:

function loadModules(modules: string[], loadScriptOptions?: ILoadScriptOptions): Promise<any[]>;

Таким образом, правильный способ сделать это, как указано выше: .then(([Map, MapView, Basemap]) => { ... }

И в этот момент мое понимание достигло предела. В следующем теле метода я могу вызывать Map, MapView и BaseMap по их именам, в то время как я ожидал, что это будет массив, к которому я должен был обращаться к javascript-ish, например Arguments[0][0], Arguments[0][1] и так далее, поскольку я передал только один объект типа Array<any>.

Пожалуйста, объясните мне, почему и как это возможно, или если я делаю что-то ужасно неправильное здесь.

1 Ответ

0 голосов
/ 09 мая 2018

Это называется деструктуризацией.

let [a, b, c] = result;

это то же самое, что и

let a = result[0];
let b = result[1];
let c = result[2];

То же самое относится к аргументам функции

function ([a,b,c]) {
}

это то же самое, что и

function (args) {
  let a = args[0];
  let b = args[1];
  let c = args[2];
}

Вы также можете выполнить деструктуризацию объекта:

let { a, b, c } = item;

так же, как:

let a = item.a;
let b = item.b;
let c = item.c;

В вашем случае код можно записать в виде:

start = () => {
    return EsriLoader.loadModules(['esri/Map', 'esri/views/MapView', "esri/Basemap"])
        .then(modules => {
            const Map = modules[0];
            const MapView = modules[1];
            const Basemap = modules[2];
            const map = new Map({
                basemap: "streets"
              });

              const view = new MapView({
                map: map,
                container: "map"
              });
        });
}
...