Javascript 在承诺链上使用 setTimeout
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39538473/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
using setTimeout on promise chain
提问by AL-zami
Here i am trying to wrap my head around promises.Here on first request i fetch a set of links.and on next request i fetch the content of first link.But i want to make a delay before returning next promise object.So i use setTimeout on it.But it gives me the following JSON error (without setTimeout() it works just fine
)
在这里,我试图围绕 promises.Here 在第一个请求中获取一组链接。在下一个请求中我获取第一个链接的内容。但我想在返回下一个 promise 对象之前延迟。所以我使用setTimeout on it.But 它给了我以下 JSON 错误 ( without setTimeout() it works just fine
)
SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
SyntaxError: JSON.parse: JSON 数据第 1 行第 1 列的意外字符
i would like to know why it fails?
我想知道为什么会失败?
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);
});
回答by jfriend00
To keep the promise chain going, you can't use setTimeout()
the way you did because you aren't returning a promise from the .then()
handler - you're returning it from the setTimeout()
callback which does you no good.
为了保持承诺链的运行,您不能使用setTimeout()
您所做的方式,因为您没有从.then()
处理程序返回承诺- 您是从setTimeout()
回调中返回它,这对您没有好处。
Instead, you can make a simple little delay function like this:
相反,您可以制作一个简单的小延迟函数,如下所示:
function delay(t, v) {
return new Promise(function(resolve) {
setTimeout(resolve.bind(null, v), t)
});
}
And, then use it like this:
然后像这样使用它:
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");
});
});
Here you're returning a promise from the .then()
handler and thus it is chained appropriately.
在这里,您从.then()
处理程序返回一个承诺,因此它被适当地链接起来。
You can also add a delay method to the Promise object and then directly use a .delay(x)
method on your promises like this:
您还可以向 Promise 对象添加一个延迟方法,然后直接.delay(x)
在您的 Promise 上使用一个方法,如下所示:
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);
});
Or, use the Bluebird promise librarywhich already has the .delay()
method built-in.
或者,使用已经内置了该方法的Bluebird 承诺库.delay()
。
回答by Igor Korsakov
.then(() => new Promise((resolve) => setTimeout(resolve, 15000)))
UPDATE:
更新:
when I need sleep in async function I throw in
当我需要在异步函数中睡眠时,我投入
await (async () => new Promise(resolve => setTimeout(resolve, 1000)))();
回答by Sébastien Rosset
The shorter ES6 version of the answer:
较短的 ES6 版本的答案:
const delay = t => new Promise(resolve => setTimeout(resolve, t));
And then you can do:
然后你可以这样做:
delay(3000).then(() => console.log('Hello'));
回答by AnoopGoudar
If you are inside a .then()block and you want to execute a settimeout()
如果您在.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!!!');
})
output will as shown below
输出将如下所示
wait for 10 seconds . . . .
10 seconds Timer expired!!!
promise resolved!!!
Happy Coding!
快乐编码!
回答by Jan
In node.js you can also do the following:
在 node.js 中,您还可以执行以下操作:
const { promisify } = require('util')
const delay = promisify(setTimeout)
delay(1000).then(() => console.log('hello'))