[Javascript] Covert async code to sync code with throwing Promise
const fetch = () =>
new Promise((res) => {
setTimeout(() => res({ user: 'zhen' }), 1150)
})
globalThis.fetch = fetch
async function getUser() {
return await fetch()
}
async function m1() {
// do something
return await getUser()
}
async function m2() {
// do something
return await m1()
}
async function m3() {
// do something
return await m2()
}
async function main() {
const user = await m3()
console.log('user', user)
}
We want to cover this async code to sync code, which means the following code should work
var fetch = () =>
new Promise((res) => {
setTimeout(() => res({ user: 'zhen' }), 1150)
})
globalThis.fetch = fetch
function getUser() {
return fetch()
}
function m1() {
// do something
return getUser()
}
function m2() {
// do something
return m1()
}
function m3() {
// do something
return m2()
}
function main() {
const user = m3()
console.log('user', user.data)
}
Of course we need to add extra code to make it works.
Idea:
It would be the similar way how React suspend works. When fetching some data using Promise, Suspend check, if you throw a Promise as error, it will wait the promise to be resolved or rejected, it stores all the data into a cache array... then the promise resolved or rejected... then it should rerun the original function again.
var fetch = () =>
new Promise((res) => {
setTimeout(() => res({ user: 'zhen' }), 1150)
})
globalThis.fetch = fetch
function getUser() {
return fetch()
}
function m1() {
// do something
return getUser()
}
function m2() {
// do something
return m1()
}
function m3() {
// do something
return m2()
}
function main() {
const user = m3()
console.log('user', user.data)
}
function run(func) {
const caches = []
let i = 0
const originalFetch = globalThis.fetch
fetch = function (...args) {
if (caches[i]) {
return caches[i]
}
const result = {
status: 'pending',
data: null,
err: null,
}
caches[i++] = result
const promise = originalFetch(...args)
.then((data) => {
result.status = 'fulfilled'
result.data = data
})
.catch((err) => {
result.status = 'rejected'
result.err = err
})
throw promise
}
try {
func()
} catch (err) {
if (err instanceof Promise) {
const rerun = () => {
i = 0
func()
}
err.then(rerun, rerun)
}
}
}
run(main)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2023-08-23 [React Typescript] ElementType, ComponentType
2023-08-23 [React Typescript] JSX.IntrinsicElements
2022-08-23 [Unit testing Express] Testing controller
2022-08-23 [Express] Extends CrudController with Mongoose model
2022-08-23 [Unit Testing] Test Mongoose model
2020-08-23 [React] Use react styled system with styled components
2019-08-23 [Cypress] install, configure, and script Cypress for JavaScript web applications -- part4