如何化解一个又一个的承诺
How to resolve promises one after another?
我怎么能一个接一个地做出承诺呢?
waitFor(t)
,是一个返回承诺的函数,该承诺在t
时间后解析。我希望能够做到的是:
waitFor(1000) Then when finished, console.log('Finished wait of 1000 millis') then
waitFor(2000) Then when finished, console.log('Finished wait of 2000 millis') then
waitFor(3000) Then when finished, console.log('Finished wait of 3000 millis')
这是我尝试的:
waitFor(1000).then(function(resolve, reject) {
console.log(resolve);
}).then(waitFor(2000).then(function(resolve, reject) {
console.log(resolve);
})).then(waitFor(3000).then(function(resolve, reject) {
console.log(resolve);
}));
不幸的是这个控制台。每隔1秒记录一次语句,这意味着所有的承诺都是一次调用的。
我设法用这样的回调来解决这个问题,但这使得一切都很难看:
waitFor(1000).then(function(resolve, reject) {
console.log(resolve+' @ '+(new Date().getSeconds()));
waitFor(2000).then(function(resolve, reject) {
console.log(resolve+' @ '+(new Date().getSeconds()));
waitFor(3000).then(function(resolve, reject) {
console.log(resolve+' @ '+(new Date().getSeconds()));
});
});
});
那么我应该如何使用承诺来做这个,使它工作,而不是使用丑陋的回调地狱?
不希望的结果:http://jsfiddle.net/nxjd563r/1/
期望结果:http://jsfiddle.net/4xxps2cg/
我找到你的解决方案了。
你需要让每个then
返回一个新的承诺,这样下一个then
可以在前一个被解决后做出反应。
waitFor(1000).then(function(result) {
$('#result').append(result+' @ '+(new Date().getSeconds())+'<br>');
return waitFor(2000);
}).then(function(result) {
$('#result').append(result+' @ '+(new Date().getSeconds())+'<br>');
return waitFor(3000);
}).then(function(result) {
$('#result').append(result+' @ '+(new Date().getSeconds())+'<br>');
});
jsfiddle http://jsfiddle.net/4xxps2cg/2/
你可以将promise放入数组中,并使用reduce
将它们链接起来,从一个额外解析的promise开始。
function waitPromise(time) {
//console.log(time);
return new Promise( (resolve,reject) => {
setTimeout( () => {resolve('resolved');}, time);
});
}
function log(data) {
return new Promise( (resolve,reject) => {
console.log( data +' @ '+(new Date().getSeconds()));
resolve();
});
}
var ps = [];
for (var i=0;i<3;i++) {
let time = (i+1) * 1000;
ps.push( () => waitPromise(time) );
ps.push( log );
}
console.log( 'started' +' @ '+(new Date().getSeconds()));
var p = Promise.resolve();
ps.reduce( (p,c) => {return p.then(c)}, p);
调用和等待的格式有点off,您的then
应该是一个返回承诺的函数,因为现在您正在传递一个函数调用而不是一个函数,它立即运行该请求,而不是等待调用函数作为承诺的结果。
应该这样做:
function waitFor(timeout) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(`Finished waiting ${timeout} milliseconds`);
}, timeout);
});
}
waitFor(1000).then(function(resolve, reject) {
$('#result').append(resolve+' @ '+new Date().getSeconds()+'<br/>');
}).then(function(){
return waitFor(2000)
}).then(function(resolve, reject) {
$('#result').append(resolve+' @ '+new Date().getSeconds()+'<br/>');
}).then(function() {
return waitFor(2000)
}).then(function(resolve, reject) {
$('#result').append(resolve+' @ '+new Date().getSeconds()+'<br/>');
})
waitFor()
似乎在.then()
时立即被调用;请尝试从.then()
匿名函数中返回waitFor()
。
可以选择创建持续时间值数组,使用Array.prototype.shift()
连续使用每个持续时间值调用waitFor
,或者将参数timeout
传递给waitFor
;如果每个.then()
都调用了相同的进程,则在waitFor
中包含.then()
链接到Promise
的进程;在.then()
处调用相同的waitFor
函数链接到初始waitFor()
调用
var t = [1000, 2000, 3000];
function waitFor(timeout) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve("`Finished waiting ${timeout} milliseconds`");
}, timeout && t.shift() || t.shift());
}).then(function (data) {
$('#result').append(data + ' @ ' + new Date().getSeconds() + '<br/>');
})
}
waitFor().then(waitFor).then(waitFor)
//.then(function() {return waitFor(5000)})
- jQuery使一个又一个充满活力
- RaphaelJS:如何制作一个又一个元素的动画
- 如何运行一个又一个脚本
- 使用 jQuery animate 时绘制一个又一个对象的线条
- 为什么当我调用一个又一个函数时,它调用的都是以前的
- 在 JavaScript 中延迟一个又一个函数的最佳方法
- 在 Ajax 加载的外部 html 中调用一个又一个脚本的事件
- JavaScript:一个又一个循环不执行
- 如何在Javascript中以过程化的方式运行一个又一个语句
- $('html').单击一个又一个单击事件
- WebGL-呈现一个又一个形状时出现问题
- 如何化解一个又一个的承诺
- 如何使用
- JavaScript Regex(替换),如果缺少一个又一个单词
- 用buzz.js播放一个又一个声音
- 从URL运行一个又一个函数
- 如何启动一个又一个脚本
- 玩一个又一个精灵表
- 如何在D3.js中运行一个又一个函数
- PhantomJS打开一个又一个页面