jQuery дважды вызовите .GET () и получите результаты - PullRequest
0 голосов
/ 11 апреля 2020

В моей программе мне нужно выполнить вызов GET, затем передать возвращенные данные другому вызову GET и затем вернуть результаты. Когда это происходит, я хочу, чтобы моя программа ожидала возвращения данных.

Сейчас я понял что-то вроде этого:

    async function getPlaceTag(lat, lng) {
        jQuery.get('https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=' + lat + '&lon=' + lng)
            .done(function (data) {
                jQuery.get('http://overpass-api.de/api/interpreter?data=[out:json];way(' + data.osm_id + ');out;')
                    .done(function (data2) {
                        console.log(data2);
                    });
            });
    }

Затем я использую это:

    mymap.on('moveend', async function () {
        let coords = myMarker.getLatLng();
        console.log('call tag');
        await getPlaceTag(coords.lat, coords.lng);  // I want to wait here until it gets done
        console.log('after call');
    })

И я получаю:

call tag
after call
[GET data]    <-- printed my data after ~1sec

Я хочу, чтобы он получил эти данные и распечатал их до того, как будет напечатано «после вызова»:

call tag
[GET data]
after call

1 Ответ

2 голосов
/ 11 апреля 2020

Вам нужно return или await результат вызова done, чтобы заставить async функцию ждать ее завершения.

Использование .then (вместо * 1008) *) и не async функция:

function getPlaceTag(lat, lng) {
    return jQuery.get('https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=' + lat + '&lon=' + lng)
        .then(function (data) {
            return jQuery.get('http://overpass-api.de/api/interpreter?data=[out:json];way(' + data.osm_id + ');out;')
                .then(function (data2) {
                    return data2;
                });
        });
}

Использование функции async с await и return:

async function getPlaceTag(lat, lng) {
    const data1 = await jQuery.get('https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=' + lat + '&lon=' + lng);
    return jQuery.get('http://overpass-api.de/api/interpreter?data=[out:json];way(' + data1.osm_id + ');out;');
}

Обратите внимание, что в обоих случаях это работает, потому что jQuery было обновлено, чтобы сделать его Deferred действительным обещанием.


FWIW, я бы не стал использовать jQuery для этого, я бы использовал стандарт fetch isntead , У меня была бы служебная функция:

async function fetchText(url, init) {
    const response = await fetch(url, init);
    if (!response.ok) {
        throw new Error("HTTP error " + response.status);
    }
    return response.text();
}

, а затем я использовал бы ее так:

async function getPlaceTag(lat, lng) {
    const data1 = await fetchText('https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=' + lat + '&lon=' + lng);
    return fetchText('http://overpass-api.de/api/interpreter?data=[out:json];way(' + data1.osm_id + ');out;')
}

Иногда у меня есть fetchJSON, когда мне нужно прочитать и проанализировать результат как JSON и др. c.

Я не просто использую fetch напрямую из-за ножа в fetch API ¹: он выполняет это обещание, даже когда есть ошибка HTTP (например, 404 или 500), вместо того, чтобы отклонять ее.


¹ Это пост в моем маленьком c небольшом блоге.

...