免费的源代码分享有哪些网站,如何自己制作一款手游,优秀的营销案例,建设学校网站的需求分析如果js一个代码块中有耗时操作#xff0c;但是return的结果可能会依赖这个耗时操作的返回#xff0c;怎么解决#xff1f;
一般人可能想到的方法就是async/await。
没错#xff0c;正常情况下是这样的#xff0c;伪代码如下#xff1a; async OuterFun() { const resul…如果js一个代码块中有耗时操作但是return的结果可能会依赖这个耗时操作的返回怎么解决
一般人可能想到的方法就是async/await。
没错正常情况下是这样的伪代码如下 async OuterFun() { const result await timeCostFunc() // timeCostFunc是耗时操作 ..... return finalResult // finalResult依赖于上面的耗时操作返回的result } 上面需要注意的是耗时操作的函数必须返回一个promise! 但是下面这种情况使用async/await就没有效果了
async _normalizeSongs(songs) {let ret [];for (const song of songs) {const songItem await createSong(song); // createSong是耗时操作ret.push(songItem);}return ret;}
这里的原因就在于 遍历数组这个步骤并不是完全同步的即便使用了async/await,也是这样。
换句话说由于js异步执行的原因而遍历数组本身并不是一个完全同步阻塞的操作就算有async/await关键字 return ret这个操作可能会在for循环之前就执行了所以返回的是一个空数组
那么问题的关键就是要把for循环和数组push整个代码块变成一个完全同步阻塞的操作
解决办法把需要完全同步的部分整体封装成一个promise, 然后再通过await 这个promise同步阻塞获取结果这样就能保证了最终return会等待前面所有异步代码执行完毕那么就不会return空值了
代码如下
async _normalizeSongs(songs) {// 将涉及到数组的耗时操作整体封装成一个promiseconst songPromise new Promise(async (resolve) {let ret [];for (const song of songs) {const songItem await createSong(song);ret.push(songItem);}resolve(ret); // 把耗时操作的结果丢给resolve。});// 等待这个promise同步阻塞获取结果const resultSongs await songPromise;return resultSongs;}