Reputation: 41
I intend to open a series of urls in firefox,each one should be opened after another in 10 minutes, here is my code should be execute in firebug console:
function sleep (time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
var urls = ["https://www.google.com/","https://www.bing.com/","https://www.reddit.com/"];
for(var i = 0; i < urls.length; i++)
sleep(600000 * i).then(() => {
window.open(urls[i]);
})
But it didn't work, could anyone help me ? Thank you~
Upvotes: 3
Views: 8366
Reputation: 25956
Promises work very well with async/await functions.
The following will declare a new asynchronous function (i.e. it will execute outside after the function is called). The code of the async function reads very easily because it reads like a synchronous function:
function sleep(delay) {
return new Promise((resolve) => setTimeout(resolve, delay))
}
(async function() {
const urls = ["https://www.google.com/","https://www.bing.com/","https://www.reddit.com/"]
for (let url of urls) {
await sleep(1000)
console.log(url)
}
})()
Here's a version using Promise chaining:
function sleep(delay) {
return new Promise((resolve) => setTimeout(resolve, delay))
}
const urls = ["https://www.google.com/","https://www.bing.com/","https://www.reddit.com/"];
let p = Promise.resolve();
for (let url of urls) {
p = p.then( function () {
return sleep(1000);
} );
p = p.then( function () {
console.log(url);
return Promise.resolve();
} );
}
Upvotes: 6
Reputation: 37815
Think a interval + entries would be better suited for this, here is an example with es6
const urls = [
'https://www.google.com/',
'https://www.bing.com/',
'https://www.reddit.com'
]
const entries = urls.entries()
const loop = setInterval(() => {
const {value, done} = entries.next()
done ? clearInterval(loop) : open(value)
}, 600 * 10)
Upvotes: 0
Reputation: 48367
Sleep
function is executing asynchronously and the for
loop finished before executing any of the sleep
calls.
So, the last value of for
loop will be 3
, and window.open
function will receive as parameter the value
of urls[3]
which is undefined.
Have a look:
function sleep (time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
var urls = ["https://www.google.com/","https://www.bing.com/","https://www.reddit.com/"];
for(var i = 0; i < urls.length; i++)
sleep(600*i).then(() => {
console.log(i);
})
One solution is to use let
keyword.
You should use let
keyword in order to use enclosed value of i
variable.
function sleep (time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
var urls = ["https://www.google.com/","https://www.bing.com/","https://www.reddit.com/"];
for(let i = 0; i < urls.length; i++)
sleep(6000*i).then(() => {
window.open(urls[i]);
})
Upvotes: 7
Reputation: 4346
The problem is i will =3 on in all 3 cases, so you need to save i for example
function sleep (time, i) {
return new Promise((resolve) => setTimeout(() => resolve(i), time));
}
var urls = ["https://www.google.com/","https://www.bing.com/","https://www.reddit.com/"];
for(var i = 0; i < urls.length; i++)
sleep(1 * i, i).then((index) => {
console.log(urls[index]);
})
But even this will not help, because first new tab will opened, your code in inactive tab will be stopped by browser.
Upvotes: 0
Reputation: 904
You could use setInterval() or setTimeout() instead of sleep to achieve this.
Upvotes: -1