我可以在Chrome任务管理器中看到运行以下代码的标签会占用越来越多的内存,并且在解析承诺之前不会发布
更新
这里的主要想法是使用单一的低级别'处理"忙"来自服务器的响应。其他方法只是将带有请求数据的url路径传递给它并等待有价值的响应。
删除了一些反模式。
var counter = 1
// emulates post requests sent with ... axios
async function post (path, data) {
let response = (counter++ < 1000) ? { busy: true } : { balance: 3000 }
return Promise.resolve(response)
}
async function _call (path, data, resolve) {
let response = await post()
if (response.busy) {
setTimeout(() => {
_call(path, data, resolve)
}, 10)
throw new Error('busy')
}
resolve(response.balance)
}
async function makePayment (amount) {
return new Promise((resolve, reject) => {
_call('/payment/create', {amount}, resolve)
})
}
async function getBalance () {
return new Promise((resolve, reject) => {
_call('/balance', null, resolve)
})
}
makePayment(500)
.then(() => {
getBalance()
.then(balance => console.log('balance: ', balance))
.catch(e => console.error('some err: ', e))
})
答案 0 :(得分:1)
您第一次在此处致电_call()
:
async function getBalance () {
return new Promise((resolve, reject) => {
_call('/balance', null, resolve)
})
}
它不会调用resolve回调,它会返回被拒绝的承诺,因此new Promise()
中的getBalance()
最初将无效。请记住,因为_call
被标记为async
,所以当你抛出时,它会被抓住并变成被拒绝的承诺。
当计时器触发时,它会拨打resolve()
,这将解析getBalance()
承诺,但它没有价值,因此您无法获得余额。当您最终调用resolve(response.balance)
时,您已经调用了resolve()
函数,因此它所属的承诺会被锁定并且不会更改其值。
正如其他人所说,这段代码存在各种各样的错误(许多反模式)。这是一个简化版本,当我在node.js中运行它或在答案中的代码片段中时可以使用:
function delay(t, val) {
return new Promise(resolve => {
setTimeout(resolve.bind(null, val), t);
});
}
var counter = 1;
function post() {
console.log(`counter = ${counter}`);
// modified counter value to 100 for demo purposes here
return (counter++ < 100) ? { busy: true } : { balance: 3000 };
}
function getBalance () {
async function _call() {
let response = post();
if (response.busy) {
// delay, then chain next call
await delay(10);
return _call();
} else {
return response.balance;
}
}
// start the whole process
return _call();
}
getBalance()
.then(balance => console.log('balance: ', balance))
.catch(e => console.error('some err: ', e))
&#13;