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 = ["/","/","/"];
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~
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./","https://www.bing./","https://www.reddit./"];
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~
Share Improve this question asked Aug 11, 2017 at 6:50 WangWang 411 silver badge4 bronze badges 1- See: stackoverflow./q/750486/5647260 – Andrew Li Commented Aug 11, 2017 at 6:53
5 Answers
Reset to default 7Sleep
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./","https://www.bing./","https://www.reddit./"];
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./","https://www.bing./","https://www.reddit./"];
for(let i = 0; i < urls.length; i++)
sleep(6000*i).then(() => {
window.open(urls[i]);
})
jsFiddle solution.
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./","https://www.bing./","https://www.reddit./"]
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./","https://www.bing./","https://www.reddit./"];
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();
} );
}
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./","https://www.bing./","https://www.reddit./"];
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.
Think a interval + entries would be better suited for this, here is an example with es6
const urls = [
'https://www.google./',
'https://www.bing./',
'https://www.reddit.'
]
const entries = urls.entries()
const loop = setInterval(() => {
const {value, done} = entries.next()
done ? clearInterval(loop) : open(value)
}, 600 * 10)
You could use setInterval() or setTimeout() instead of sleep to achieve this.