.then 运行 在数据从 fetch 返回之前

.then running before data is returned from fetch

我想要show_name()到运行然后调用另一个函数。我不明白为什么 show_name().then 会失败。我可能忽略了一些东西。

            async function show_name() {
                
               flights_xml.forEach( (flt, i) => {setTimeout(() => {
                    if (document.getElementById('show_dx_name').checked) {
                    
                        let serial_from_xml = flt.children[7].innerHTML;

                        // async function getDxrName633() {
                            const serialNumber = { serial_from_xml };
                            
                            const options = {
                                method: 'POST', 
                                headers: { 'Content-Type': 'application/json' },
                                body: JSON.stringify(serialNumber)
                            };

                                fetch('/recall633', options)
                                .then(response => response.json()) 
                                .then(json => {
                                    let parser = new DOMParser();
                                    let a633XML =  parser.parseFromString(json, "application/xml");
                                    Formats = a633XML.querySelector('Formats');
                                    a633 = Formats.children[1].innerHTML;
                                    a633b4ParsedToXML = $('<textarea />').html(a633).text(); 
                                    a633 = parser.parseFromString(a633b4ParsedToXML, "text/xml")
                                    console.log(a633)
                                    console.log("Author: " + a633.children[0].children[4].children[0].children[0].innerHTML)                                                                                                
                                })
                        // }

                            // getDxrName633().then(()=>{
                            //     console.log("This will work but I don't need it to run every time...it's a waste");
                            // })

                            } // END IF ..show
                        }) // END SetTimeout
                }) // END foreach

        } // END async show_name
        show_name().then(() => {
            console.log("Why is this running before the fetch .then ?? ...weird"); //
        })

这是一个简化版本,您可以将其应用到您的代码中。

const promArr = flights_xml.map( async (flt, i) => {
  const res = await fetch('/recall633', options)
  return await res.json()
  })
const doneAll = await Promise.all(promArr)
console.log('Fetched all')
doneAll.forEach( fetched => {
  // Do your DOM parsing here
}

看,我重构你的代码...

基本上,我把forEach换成了forof...,并且,我用了await...希望能帮到你。我使用了 Promise 响应...

        async function show_name() {
            return new Promise( async (resolve) => {
                for (const flt of flights_xml) {

                    if (document.getElementById('show_dx_name').checked) {
                        let serial_from_xml = flt.children[7].innerHTML;
                        // async function getDxrName633() {
                            const serialNumber = { serial_from_xml };
                            const options = {
                                method: 'POST', 
                                headers: { 'Content-Type': 'application/json' },
                                body: JSON.stringify(serialNumber)
                            };

                            const response = await fetch('/recall633', options);
                            const json = response.json();
                            let parser = new DOMParser();
                            let a633XML =  parser.parseFromString(json, "application/xml");
                            Formats = a633XML.querySelector('Formats');
                            a633 = Formats.children[1].innerHTML;
                            a633b4ParsedToXML = $('<textarea />').html(a633).text(); 
                            a633 = parser.parseFromString(a633b4ParsedToXML, "text/xml")
                            console.log(a633)
                            console.log("Author: " + a633.children[0].children[4].children[0].children[0].innerHTML)                                                                                                

                            } // END IF ..show
                }
                resolve('And now?');
            });

    } // END async show_name

    show_name()
        .then(() => {
            console.log("Why is this running before the fetch .then ?? ...weird"); //
        });

TL;DR; something.forEach()不等。

两者都试过了,但是@jamomani 的回答由于 flt 是一个对象而出错。事实证明,如果地图是对象,地图将不起作用。

我的回答是基于@gabrielrincon 的回答。结果证明这个承诺是不必要的,需要等待 response.json().

    for (const flt of flights_xml) {
            console.log(flt) // flt is an object
        if (document.getElementById('show_dx_name').checked) {
            let serial_from_xml = flt.children[7].innerHTML;
            console.log(serial_from_xml)
            // async function getDxrName633() {
                // let serial_from_xml = 21348
                const serialNumber = { serial_from_xml };
                console.log(serialNumber)
                const options = {
                    method: 'POST', 
                    headers: { 'Content-Type': 'application/json' },
                    // body: JSON.stringify(serialNumber)
                    body: JSON.stringify(serialNumber)
                };

                let response = await fetch('/recall633', options)
                        // .then(response => response.json()) <-- this also works
                        // .then(json => {
                let json = await response.json()           
                // let json = response.json(); <-- Doesn't work; need to await
                let parser = new DOMParser();
                let a633XML =  parser.parseFromString(json, "application/xml");
                Formats = a633XML.querySelector('Formats');
                a633 = Formats.children[1].innerHTML;
                a633b4ParsedToXML = $('<textarea />').html(a633).text(); // converts from encoded to xml tags
                a633 = parser.parseFromString(a633b4ParsedToXML, "text/xml")
                console.log(a633)
                console.log("Author: " + a633.children[0].children[4].children[0].children[0].innerHTML)      
                } // END IF ..show
    } // end for
} // END async show_name
show_name()
    .then(() => {
        console.log("This is finally waiting for the fetch .then - excellent!"); //
    });