151

別のアクションを実行する前にJavaScriptでスリープを実行する方法はありますか?

例:

 var a = 1+3;
 // Sleep 3 seconds before the next action here
 var b = a + 4;
4

14 に答える 14

156

setTimeout同様の効果を得るために使用できます。

var a = 1 + 3;
var b;
setTimeout(function() {
    b = a + 4;
}, (3 * 1000));

これは実際には JavaScript を「スリープ」させるわけではなく、渡された関数をsetTimeout特定の期間 (ミリ秒単位で指定) 後に実行するだけです。JavaScript に sleep 関数を書くことも可能ですがsetTimeout、sleep 期間中にすべてをフリーズさせるわけではないので、可能であれば使用することをお勧めします。

于 2009-04-17T01:37:36.717 に答える
16

ECMAScript 6 バージョン、「コード ブロッキング」に生成器を生成する:

元の質問は 7 年前に投稿されたので、正確なコードで回答するのは面倒でした。なぜなら、それはあまりにも簡単で、すでに回答済みだからです。これは、少なくとも 2 つのスリープが必要な場合や、非同期実行のシーケンスを計画している場合など、より複雑な問題に役立ちます。必要に応じて自由に変更してください。

let sleeptime = 100
function* clock()
{
    let i = 0
    while( i <= 10000 )
    {
        i++
        console.log(i); // actually, just do stuff you wanna do.
        setTimeout(
            ()=>
            {
                clk.next()
            }
            , sleeptime
        )
        yield
    }
}

let clk = clock()
clk.next()

関数*

() => アロー関数

Promisesを介してイベントをチェーンすることもできます:

function sleep(ms)
{
    return(
        new Promise(function(resolve, reject)
        {
            setTimeout(function() { resolve(); }, ms);
        })
    );
}


sleep(1000).then(function()
{
    console.log('1')
    sleep(1000).then(function()
    {
        console.log('2')
    })
})

または、はるかに単純であまり派手でない方法は

function sleep(ms, f)
{
    return(
        setTimeout(f, ms)
    )
}


sleep(500, function()
{
    console.log('1')
    sleep(500, function()
    {
        console.log('2')
    })
})
console.log('Event chain launched')

何らかの条件が発生するのを待っているだけなら、このように待つことができます

function waitTill(condition, thenDo)
{
    if (eval(condition))
    {
        thenDo()
        return
    }

    setTimeout(
        ()    =>
        {
            waitTill(condition, thenDo)
        }
        ,
        1
    )
}

x=0

waitTill(
    'x>2 || x==1'
    ,
    ()    =>
    {
        console.log("Conditions met!")
    }
)

// Simulating the change
setTimeout(
    () =>
    {
        x = 1
    }
    ,
    1000
)

于 2016-06-28T19:22:57.500 に答える
13

2018年アップデート

最新の Safari、Firefox、および Node.js も、async/await/promises をサポートするようになりました。

async/await/Promises の使用:

(2017 年 1 月現在、Chrome でサポートされていますが、Safari、Internet Explorer、Firefox、Node.js ではサポートされていません)

'use strict';

function sleep(ms) {
  return new Promise(res => setTimeout(res, ms));
}

let myAsyncFunc = async function() {
  console.log('Sleeping');
  await sleep(3000);
  console.log('Done');
}

myAsyncFunc();

2017年アップデート

この質問がされてから JavaScript は進化し、現在ではジェネレーター関数があり、新しい async/await/Promise が展開されています。以下に 2 つのソリューションを示します。1 つは最新のすべてのブラウザーで動作するジェネレーター関数を使用するもので、もう 1 つはまだどこでもサポートされていない新しい async/await を使用するものです。

ジェネレーター関数の使用:

'use strict';

let myAsync = (g) => (...args) => {
    let f, res = () => f.next(),
        sleep = (ms) => setTimeout(res, ms);
    f = g.apply({sleep}, args); f.next();
};

let myAsyncFunc = myAsync(function*() {
    let {sleep} = this;
    console.log("Sleeping");
    yield sleep(3000);
    console.log("Done");
});

myAsyncFunc();

これらのソリューションはどちらも本質的に非同期であることに注意してください。これは、スリープ中に myAsyncFunc (どちらの場合も) が返されることを意味します。

この質問は、sleep() の JavaScript バージョンは何ですか? とは異なることに注意してください。リクエスターは、アクション間の遅延ではなく、実際のスリープ (プロセスで他のコードを実行しない) を求めています。

于 2017-01-11T18:04:33.943 に答える
3

setTimeoutおよびよりも不格好な関数が必要な場合setIntervalは、引数の順序を逆にして適切な名前を付けるだけの関数でそれらをラップできます。

function after(ms, fn){ setTimeout(fn, ms); }
function every(ms, fn){ setInterval(fn, ms); }

CoffeeScript のバージョン:

after = (ms, fn)-> setTimeout fn, ms
every = (ms, fn)-> setInterval fn, ms

その後、無名関数でうまく使用できます。

after(1000, function(){
    console.log("it's been a second");
    after(1000, function(){
        console.log("it's been another second");
    });
});

「Nミリ秒後、...」(または「Nミリ秒ごと、...」)と簡単に読み取れるようになりました。

于 2016-07-16T03:43:51.083 に答える
1

setTimeout指定した時間の経過後にコールバックを呼び出すために使用できます。

setTimeout(() => {
    console.log('Called after 1 second');
}, 1000);

promise として使用する場合はsetTimeout、次のようにすることができます。

const delay = milliseconds => new Promise(resolve => { setTimeout(resolve, milliseconds); });

await delay(1000);

console.log('Called after 1 second');

Node.js 16 以降、この機能も組み込まれています。

import {setTimeout as delay} from 'node:timers/promises';

await delay(1000);

console.log('Called after 1 second');

Node.js またはメイン スレッド外のブラウザで同期遅延が必要な場合は、次を使用できますAtomics.wait

const delay = milliseconds => Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, milliseconds);

await delay(1000);

console.log('Called after 1 second');
于 2019-03-16T04:15:22.297 に答える