Я звоню на URL и пытаюсь получить данные в формате JSON, которые я в основном скопировал из других ответов в StackOverflow. Однако responseData.title имеет два разных значения в двух вызовах, которые я делаю во втором вызове .then() ниже:

var getTitleForId = async function(id) {
    if (!id)
        return false

    let url = id + "other stuff to make a valid api call"

    let response = '(null)'

    await fetch(url)
        .then((resp) => resp.json())
        .then((responseData) => {
            console.log(responseData.title);
            response = responseData.title;
    })

    return response
}

В первом вызове console.log(responseData.title) журнал показывает поле заголовка из ответа json.

Во втором вызове response = responseData.title (который позже возвращается в методе) присваивает [object Promise] response, который, как я полагаю, является обещанием toString()

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

Изменить: под "вторым звонком" я имею в виду второй раз, когда я получаю доступ. Если вы посмотрите на код сейчас, я имею в виду, что когда я возвращаю ответ, который, как я предполагал, будет назначен responseData.title, он будет назначен [object Promise]

Edit2: Также я понимаю, что '(null)' никогда не будет передано, независимо от того, что происходит. Это просто пережиток одного из многих случаев, когда я пытался сделать эту работу.

Edit3: я добавил все тело метода

2
realmature 23 Фев 2018 в 18:43

4 ответа

Лучший ответ

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

В то же время это может помочь

Попробуйте сделать это

var title = await fetch(url)
    .then(resp => resp.json())
    .then(responseData => responseData.title);

console.log(title);

Или это

var titlePromise = fetch(url)
    .then(resp => resp.json())
    .then(responseData => responseData.title);

titlePromise.then(console.log)

Или как функция (почему бы и нет?)

var getTitle = url => fetch(url)
    .then(resp => resp.json())
    .then(responseData => responseData.title);

getTitle(url).then(console.log)

Редактировать: Глядя на ваш код, я предполагаю, что вы просто вызываете свою функцию getTitleForId без каких-либо ожиданий или обработки обещаний. Функция async всегда возвращает обещание; здесь то, что вы получаете, когда вызываете эту функцию, является объектом типа Promise (string) .

https://www.twilio.com/blog/2015/10/asyncawait-the-hero-javascript-deserved.html

1
Overcl9ck 23 Фев 2018 в 19:53

Вы используете await , поэтому на самом деле нет необходимости беспокоиться о запутанном синтаксисе then .

Ваш код может быть переписан так:

const resp = await fetch(url);
const responseData = resp.json();
console.log(responseData.title);
const response = responseData.title;
console.log(response); // prints the title
0
Patrick Hund 23 Фев 2018 в 16:10

Вы должны вернуть свой ответ в течение первого then() вызова.

await fetch(url)
    .then((resp) => {
        return resp.json()
     })
    .then((responseData) => {
        console.log(responseData.title);
        response = responseData.title;
    })
0
Michael Czechowski 23 Фев 2018 в 15:48

Я думаю, что это должно работать:

await fetch(url)
    .then((resp) => Promise.resolve(resp.json()))
    .then((responseData) => {
        console.log(responseData.title);
        response = responseData.title;
    })
0
John Detlefs 23 Фев 2018 в 16:09