Quiero probar myFunction() , que se espera que cambie var appState de "old state" a "new state" . Sin embargo, myFunction() invoca n funciones fetcher() que contienen la función asíncrona fetch , similar al psudocódigo a continuación.
// Application code myFunction() = function { for (var i = 0, len = myarray.length; i < len; i++) { fetcher() } } fetcher = function(){ fetch(url) // Is asynchronous .then(response => response.json()) .then(data => { if(data == 'abc'){ appState = "new state" } } } // Test myFunction() setTimeout(() => { assert.equal(appState, "New State") }, 10); Este tiempo de espera funciona bien y la prueba pasa, pero se siente como un olor a código. ¿Existe una forma más correcta de esperar a que se completen las funciones asincrónicas generadas por myFunction() antes de probar el nuevo estado?
¡async/await es el camino a seguir!
// Application code myFunction() = async function { for (var i = 0, len = myarray.length; i < len; i++) { await fetcher() } } fetcher = async function(){ const respons = await fetch(url) // Is asynchronous const data = await response.json()) if(data == 'abc'){ appState = "new state" } } // Your test now should look like this: async function test() { await myFunc() assert.equal(appState, "New State") } test()async/await es increíble!
Tendría que utilizar promesas o usar Async/Await
const fakeFetch = (url) => new Promise((resolve) => { setTimeout(() => { resolve({ json: () => new Promise((resolveJSON) => resolveJSON({ myKey: url === 3 ? 'abc' : 'foo' })), }); }, Math.ceil(1000 * Math.random())); }); let appState = 'x'; const myarray = [0, 1, 2, 3, 4]; const myFunction = function() { var myPromises = []; for (var i = 0, len = myarray.length; i < len; i++) { myPromises.push(fetcher(myarray[i])) } return Promise.all(myPromises); // return Promise.allSettled(myPromises); } // const myFunction = function() { // return Promise.allSettled(myarray.map(x => fetcher(x))); // } const fetcher = function(url) { return fakeFetch(url) .then(response => response.json()) .then(data => { if (data.myKey == 'abc') { appState = "new state" } }); } myFunction().then( function () { console.assert(appState === "New State", "appState", appState); }); const fakeFetch = (url) => new Promise((resolve) => { setTimeout(() => { resolve({ json: () => new Promise((resolveJSON) => resolveJSON({ myKey: url === 3 ? 'abc' : 'foo' })), }); }, Math.ceil(1000 * Math.random())); }); let appState = 'x'; const myarray = [0, 1, 2, 3, 4]; const myFunction = async function() { for (var i = 0, len = myarray.length; i < len; i++) { await fetcher(myarray[i]) } } const fetcher = async (url) => { const response = await fakeFetch(url); const data = await response.json(); if (data.myKey == 'abc') { appState = "new state" } } const test = async () => { await myFunction(); console.assert(appState === "New State", "appState", appState); }; test();