最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript sleep function by Promise in loop - Stack Overflow

programmeradmin1浏览0评论

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
Add a ment  | 

5 Answers 5

Reset to default 7

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./","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.

发布评论

评论列表(0)

  1. 暂无评论