var gameArr = { codeOne:[ { code: "code1", }, ], codeTwo:[ { code: "code2", }, ], } Object.keys(gameArr).forEach(function(j,k){ for(var i = 0; i < gameArr[j].length; i++){ accountApi({ code: gameArr[j][i].code }).then(res => { console.log(gameArr[j][i]) }).catch(err => { }) } }) // Printout: undefined
We all know that JS is single threaded. JS code can only run on one thread. The code interface above turns over a new thread, so we can't get the main thread.
In the project, some logic or requests depend on another asynchronous request. After consulting the relevant materials, I see that the higher solution is await async.
Async is short for "asynchronous", while await can be considered short for async wait. Therefore, it should be well understood that async is used to declare that a function is asynchronous, while await is used to wait for the execution of an asynchronous method to complete. Moreover, await can only appear in async functions, otherwise an error will be reported.
async function:
When calling a async Function returns a promise object. When this async When the function returns a value, promise The resolve method of is responsible for passing this value; When async Promise when the function throws an exception The reject method of will also pass this exception value.
async There may be an await expression in the function, which makes async Function pause, wait The Promise result is displayed, and then the async function is resumed and the resolved value is returned.
Effect of await:
The await expression pauses the execution of the current async function and waits for Promise processing to complete. If Promise is processed normally (fully), the resolve function parameter of its callback is used as the value of await expression to continue to execute async function.
If Promise handles the rejected exception, the await expression will throw the reason for the Promise exception. In addition, if the value of the expression after the await operator is not a Promise, the value itself is returned.
function getData(data) { return accountApi({code:data}) } async function asyncCall() { Object.keys(gameArr).forEach(function(j,k){ for(var i = 0; i < gameArr[j].length; i++){ await getData(gameArr[j][i].gameCode) } }) } asyncCall()
When async is used in forEach to report an error, it should be that forEach does not know the asynchronous function that await iterates
Replace with the following:
function getData(data) { return accountApi({code:data}) } async function asyncCall() { for (let j of Object.keys(gameArr)){ for(var i = 0; i < gameArr[j].length; i++){ await getData(gameArr[j][i].gameCode) } } } asyncCall()
Wait, I carefully found that requesting an interface returns success or error before requesting the next interface. I initiated several requests. There was a certain time in the request. There was a lot of time, and the user experience was poor.
I add this red circle and print it out. It can be seen that after the execution, the next one will be executed
function getData(data) { console.log(new Date()) return new Promise(resolve => { accountApi({code:data}) setTimeout(() => { resolve('resolved2'); }, 2000); }); } async function asyncCall() { for (let j of Object.keys(gameArr)){ for(var i = 0; i < gameArr[j].length; i++){ var data = await getData(gameArr[j][i].gameCode) } } console.log(data) } asyncCall() // Printout: // Fri Nov 12 2021 23:05:31 GMT+0800 (China standard time) // Fri Nov 12 2021 23:05:33 GMT+0800 (China standard time) // resolved2
It is necessary to implement all at once, as follows:
function getData(data) { console.log(new Date()) return new Promise(resolve => { accountApi({code:data}) setTimeout(() => { resolve('resolved2'); }, 2000); }); } async function asyncCall() { for (let j of Object.keys(gameArr)){ for(var i = 0; i < gameArr[j].length; i++){ var data = getData(gameArr[j][i].gameCode) } } var data1 = await data console.log(data1) } asyncCall() // Printout: // Fri Nov 12 2021 23:18:35 GMT+0800 (China standard time) // Fri Nov 12 2021 23:18:35 GMT+0800 (China standard time) // resolved2
The optimization idea of sending all interfaces at the same time, and the final code:
function getData(data) { return accountApi({code:data}) } async function asyncCall() { for (let j of Object.keys(gameArr)){ for(var i = 0; i < gameArr[j].length; i++){ var data = getData(gameArr[j][i].gameCode) } } await data } asyncCall()