2017-03-01 8 views
0

Ich bin über ein Array iterieren und einen REST-API-Aufruf für jedes Element, aber ich habe Probleme mit der Async-Natur von js. Ich versuche async/await zu verwenden, aber ich denke nicht, dass ich es richtig einstelle, weil es nicht auf die Antwort wartet und unbestimmt zurückkommt.Warten auf API-Antwort in einer Schleife

onSearchSuccess = async (response) => { 
    const persons = response._embedded.persons_search_collection; 
    const personsWithClasses = await persons.reduce(
    (acc, person) => { 
    const params = { 
     person_id: person.person_id, 
     date: '2017-01-05', 
     enrollment_status: 3, 
     class_status: 2, 
    }; 
    return getClasses(//this function does an GET request and returns the response 
     params, 
     (classesResponse) => { 
     const { classes } = classesResponse._embedded; 
     console.log(classes); //logs after the console.log below 
     return [...acc, { ...person, classes }]; 
     }, 
    () => acc, 
    ); 
    }, []); 
console.log(personsWithClasses); //return undefined 
} 


export const getClasses = (params, success, error) => { 
    axios.get(`${uri}/classes`, { params }) 
    .then(({ data }) => { 
    success(data); 
    }) 
    .catch(err => error(err)); 
}; 
+0

Wenn "getClasses" -Klassen eine Verheißung zurückgeben, dann können Sie '[... acc]' nicht tun, weil 'acc' ein Versprechen ist. Warum benutzt du 'reduce' hier? Was * genau * willst du erreichen? Möchten Sie alle REST nacheinander ausführen? Oder einfach warten, bis alle Anfragen erledigt sind? –

+0

Grundsätzlich habe ich eine Reihe von Leuten, ich mache eine Anfrage, um die Klassen für jede Person zu bekommen, wenn es Klassen an diesem Tag für diese Person gibt dann ein Objekt mit der Person und der Person Klassen zurückgeben, ansonsten einfach den Akku zurückgeben und fahre fort. Ich möchte im Grunde die Leute ohne Klassen ausfiltern und ein neues Objekt mit den Eigenschaften der Person und den Klassen zurückgeben, wenn sie es tun. –

+0

Würde es helfen, wenn ich den Code für 'getClasses' zur Verfügung stelle? –

Antwort

1

Wie ich in den Kommentaren erwähnt, wird reduce nicht arbeiten, wie Sie wollen, wenn Sie Asynchron-Funktionen aufrufen. Sie können Promise.all und .map verwenden, wie so (ich versuchte async/await so viel wie möglich zu verwenden):

onSearchSuccess = async (response) => { 
    const persons = response._embedded.persons_search_collection; 
    let personsWithClasses = await Promise.all(persons.map(async (person) => { 
    try { 
     const classes = await getClasses({ 
     person_id: person.person_id, 
     date: '2017-01-05', 
     enrollment_status: 3, 
     class_status: 2, 
     }); 

     return {...person, classes}; 
    } catch(error) { 
     // ignore errors if a person wasn't found 
     return null; 
    } 
    })); 
    personsWithClasses = personsWithClasses.filter(x => x != null); 
    console.log(personsWithClasses); 
} 


export const getClasses = params => { 
    return axios.get(`${uri}/classes`, { params }); 
}; 

Auch die Änderungen beachten ich getClasses gemacht. Es gibt keinen Grund, Callbacks zu akzeptieren, wenn axios.get trotzdem ein Versprechen zurückgibt.

+0

danke! Ich habe vergessen, mit dem Promise.all-Code zu aktualisieren, den ich benutzte, aber ich kam näher. Hatte einfach nicht den Versuch/Fang Teil. –

Verwandte Themen