承诺的决心范围



我正在调用一个第三方库函数。它返回结果(从他们的api(和一个回调函数,我可以为下一组结果调用该函数。

简单地说,我创建了一个模拟的第三方函数。

我的问题是为什么resolve在第一次之后没有解决承诺。我猜这是因为resolve的作用域在第三方库的内部函数中。

我该怎么解决这个问题?有更好的方法来实现这一点吗?

// Third party function, I cannot control
function thirdParty(callback) {
var number = 0;
var inner = function() {
setTimeout(function() {
next = inner;
number = number + 10;
callback(number, next);
}, 1000);
};
inner();
}
// Code I can control
var nextFunc = null;
// Calls third party api
function getNumber() {
return new Promise(function(resolve, reject) {
if (nextFunc) {
nextFunc();
} else {
thirdParty(function(number, next) {
	console.log(number);
nextFunc = next;
resolve(number);
});
}
});
}
function onButtonClick() {
getNumber().then(function(number) {
document.getElementById('ele').innerHTML += number + '<br>';
});
}
<p>
<button type="button" onClick="onButtonClick();">Get Numbers
</button>
</p>
<p id="ele"></p>

它没有解决,因为nextFunc()最终在第一个承诺内调用传递给thirdParty()的回调,并在该承诺上再次调用resolve(),该承诺已经解决,所以它什么也不做。同时,您永远不会在第二次承诺时调用resolve(),因此它永远不会解决。

考虑到您的第三方API(在我看来,它的接口设计很糟糕(的限制,这里有一个更好的方法是我能想到的唯一方法:

// Third party function, I cannot control
function thirdParty(callback) {
var number = 0;
var inner = function() {
setTimeout(function() {
next = inner;
number = number + 10;
callback(number, next);
}, 1000);
};
inner();
}
// Code I can control
const numbers = getNumbers();
// Calls third party api
async function* getNumbers() {
let resolve, next;
yield new Promise(_resolve => {
resolve = _resolve;
thirdParty((number, _next) => {
console.log(number);
resolve(number);
next = _next;
});
});
while (true) {
yield new Promise(_resolve => {
resolve = _resolve;
next();
});
}
}
document.querySelector('button').addEventListener('click', () => {
numbers.next().then(({ value }) => {
document.getElementById('ele').innerHTML += value + '<br>';
});
});
<p>
<button type="button">Get Numbers</button>
</p>
<p id="ele"></p>

最新更新