我正在尝试确定一种方法来“暂停”我的Promises代码,直到条件为真,可能是通过使用递归setTimeout()
。对于我的简单示例,我手动设置waitValue
。
我需要等待片刻,如果waitValue
仍然是假的,那么只需继续等待。当然,当waitValue
变为真时,继续处理。以下是我到目前为止拼凑的内容:
var counter=0;
function promiseTest() {
return new Promise( (resolve, reject) => {
if ( waitValue ) {
console.log('waitValue is now true');
resolve('FIRST PROMISE');
} else { // we need to wait again
if ( counter > 1000 ) { // dont wait forever.
reject('waited too long');
} else {
console.log('WAIT MESSAGE: ' + counter++ );
setTimeout( promiseTest, 3000);
}
}
})
.then( result => {
return(`SECOND PROMISE: the result is: ${result}`);
});
}
使用它:
promiseTest().then( (result)=>{ console.log('LOCAL MESSAGE: ' + result); });
以下工作正常:
var waitValue = true;
promiseTest().then( (result)=>{ console.log('LOCAL MESSAGE: ' + result); });
// waitValue is now true
// LOCAL MESSAGE: SECOND PROMISE: the result is: FIRST PROMISE
但是,以下似乎并不像我想要的那样完成:
var waitValue = false;
promiseTest().then( (result)=>{ console.log('LOCAL MESSAGE: ' + result); });
// waiting messages appear as expected
waitValue = true;
// waitValue is now true
// no other messages
我一直无法找到暂时执行的承诺示例。普通的javaScript示例可能如下所示:
var waitValue = false;
var counter = 0;
(function tester() {
if ( waitValue ) {
console.log('finally true');
} else {
if ( counter > 1000 ) {
console.log('waited too long');
process.exit;
} else {
console.log('still waiting, counter = ' + counter++);
setTimeout(tester, 1000);
}
}
})();
// wait a few seconds and enter this into the console:
var waitValue = false;
Promises脚本暂时暂停执行会是什么样的?或者也许不应该像这样使用Promise?
非常感谢。
答案 0 :(得分:1)
这个想法是朝着正确的方向发展的。当你以递归方式调用函数时,你只需要解决当前的承诺,否则你当前的承诺永远不会实现。
但请注意,如果等待时间很长,则会创建一堆promises。
function promiseTest(counter = 1000) {
return new Promise( (resolve, reject) => {
if ( waitValue ) {
console.log('waitValue is now true');
resolve('FIRST PROMISE');
} else if ( counter <= 0 ) { // dont wait forever.
reject('waited too long');
} else {
console.log('Count down: ' + counter);
setTimeout( _ => { // make sure to call `resolve` after the nested promise resolved:
promiseTest(counter-1).then(resolve);
}, 3000);
}
})
.then( result => {
return `SECOND PROMISE: the result is: ${result}`;
});
}
var waitValue = false;
promiseTest().then ( result => {
console.log('done:', result);
});
// schedule the change of the waitValue:
setTimeout(_ => waitValue = true, 4000);
&#13;
注意输出将如何解决每个已解决的嵌套链式承诺的痕迹。
我发现对你在 Promise
构造函数回调中定义的函数执行递归调用更直观,而不是在创建Promise
的函数上执行。这样你就可以创建一个承诺,并且避免出现在你的想法中的promise constructor anti-pattern(以及它的上述工作版本):
function promiseTest(counter = 1000) {
return new Promise( (resolve, reject) => {
(function loop(counter) {
if ( waitValue ) {
console.log('waitValue is now true');
resolve('FIRST PROMISE');
} else if ( counter <= 0 ) { // dont wait forever.
reject('waited too long');
} else {
console.log('Count down: ' + counter);
setTimeout( loop.bind(null, counter-1), 3000);
}
})(counter); // initial value of count-down
})
.then( result => {
return `SECOND PROMISE: the result is: ${result}`;
});
}
var waitValue = false;
promiseTest().then ( result => {
console.log('done:', result);
});
// schedule the change of the waitValue:
setTimeout(_ => waitValue = true, 4000);
&#13;
请注意输出与第一个版本略有不同,这反映出只涉及一个new
承诺
注意:它不是必需的,但我更喜欢从某个值(1000)开始倒计时,并将其作为参数传递给执行循环的匿名函数。
答案 1 :(得分:0)
setTimeout( promiseTest, 3000);
不起作用,这可能会再次调用promiseTest
函数,但永远不会解析在最外层调用中创建的承诺。
而不是乱用回调,promisify你正在使用的异步原语,setTimeout
:
function wait(t) {
return new Promise(resolve => {
setTimeout(resolve, t);
});
}
然后在轮询功能中使用它:
function promiseTest(counter = 1000) {
if (waitValue) {
console.log('waitValue is now true');
return Promise.resolve('FIRST PROMISE');
} else if (counter <= 0) { // dont wait forever.
return Promise.reject(new Error('waited too long'));
} else {
console.log('WAIT MESSAGE: ' + counter );
return wait(3000).then(() => {
return promiseTest(counter-1);
});
}
}