在这里,我试图围绕promises.Here第一次请求我获取一组链接。在下一个请求我获取第一个链接的内容。但我想在返回下一个promise对象之前做出延迟。所以我在它上面使用了setTimeout。但是它给了我以下JSON错误( without setTimeout() it works just fine
)
SyntaxError:JSON.parse:第1行第1列的意外字符 JSON数据
我想知道它失败的原因?
let globalObj={};
function getLinks(url){
return new Promise(function(resolve,reject){
let http = new XMLHttpRequest();
http.onreadystatechange = function(){
if(http.readyState == 4){
if(http.status == 200){
resolve(http.response);
}else{
reject(new Error());
}
}
}
http.open("GET",url,true);
http.send();
});
}
getLinks('links.txt').then(function(links){
let all_links = (JSON.parse(links));
globalObj=all_links;
return getLinks(globalObj["one"]+".txt");
}).then(function(topic){
writeToBody(topic);
setTimeout(function(){
return getLinks(globalObj["two"]+".txt"); // without setTimeout it works fine
},1000);
});
答案 0 :(得分:136)
为了保持承诺链,你不能像你所做的那样使用setTimeout()
,因为你没有从.then()
处理程序返回一个承诺 - 你从{{返回} 1}}回调对你没有好处。
相反,你可以制作一个简单的小延迟函数:
setTimeout()
然后,就像这样使用它:
function delay(t, v) {
return new Promise(function(resolve) {
setTimeout(resolve.bind(null, v), t)
});
}
在这里,您将从getLinks('links.txt').then(function(links){
let all_links = (JSON.parse(links));
globalObj=all_links;
return getLinks(globalObj["one"]+".txt");
}).then(function(topic){
writeToBody(topic);
// return a promise here that will be chained to prior promise
return delay(1000).then(function() {
return getLinks(globalObj["two"]+".txt");
});
});
处理程序返回一个承诺,因此它被链接得恰当。
您还可以向Promise对象添加延迟方法,然后直接在您的承诺上使用.then()
方法,如下所示:
.delay(x)
或者,使用内置function delay(t, v) {
return new Promise(function(resolve) {
setTimeout(resolve.bind(null, v), t)
});
}
Promise.prototype.delay = function(t) {
return this.then(function(v) {
return delay(t, v);
});
}
Promise.resolve("hello").delay(500).then(function(v) {
console.log(v);
});
方法的Bluebird promise library。
答案 1 :(得分:56)
.then(() => new Promise((resolve) => setTimeout(resolve, 15000)))
答案 2 :(得分:17)
答案的较短的ES6版本:
const delay = t => new Promise(resolve => setTimeout(resolve, t));
然后您可以这样做:
delay(3000).then(() => console.log('Hello'));
答案 3 :(得分:4)
如果您位于 .then()块中,并且您想要执行 settimeout()
.then(() => {
console.log('wait for 10 seconds . . . . ');
return new Promise(function(resolve, reject) {
setTimeout(() => {
console.log('10 seconds Timer expired!!!');
resolve();
}, 10000)
});
})
.then(() => {
console.log('promise resolved!!!');
})
输出如下所示
wait for 10 seconds . . . .
10 seconds Timer expired!!!
promise resolved!!!
快乐的编码!
答案 4 :(得分:1)
在node.js中,您还可以执行以下操作:
const { promisify } = require('util')
const delay = promisify(setTimeout)
delay(1000).then(() => console.log('hello'))