尝试使用setTimeout

时间:2017-09-15 05:52:10

标签: javascript node.js

鉴于我在命令行中使用node fileName.js 运行的以下代码,它似乎在循环中运行 all 项目,然后在最后睡眠......有点像是全部并行运行。

我希望代码在setTimeout期间阻止/暂停,而不是仅在setTimeout完成后运行该函数。或者,如果setTimeout不正确,则使用不同的方法,在此用例中。

const removeUsers = async () => {
    const users = await db.getUsers(); // returns 32 users.

    // Split the users up into an array, with 2 users in each 'slot'.
    var arrays = [], size = 2;
    while (users.length > 0) {
        arrays.push(users.splice(0, size));
    }

    // Now, for each slot, delete the 2 users then pause for 1 sec.
    arrays.forEach(a => {
        console.log(++counter;);

        // Delete 2x users.
        a.forEach(async u => {
            console.log('Deleting User: ' + u.id);
            await 3rdPartyApi.deleteUser({id: u.id});
        });

        // Now pause for a second.
        // Why? 3rd party api has a 2 hits/sec rate throttling.
        setTimeout(function () { console.log('Sleeping for 1 sec'); }, 1000);
    });
}

并且日志是这样的..

1.
Deleting User: 1
Deleting User: 2
2.
Deleting User: 3
Deleting User: 4
3.
...
(sleep for 1 sec)
(sleep for 1 sec)
(sleep for 1 sec)
...
end.

看看睡眠是不是感觉它会阻塞..它只是触发一个睡眠命令,然后在一秒钟后处理......

这就是我真正追求的......

1.
Deleting User: 1
Deleting User: 2
(sleep for 1 sec)
2.
Deleting User: 3
Deleting User: 4
(sleep for 1 sec).
3.
...
end.

1 个答案:

答案 0 :(得分:1)

这会调用一堆async函数。它们各自返回一个promise(async函数总是返回promises),并且这些promise将被丢弃,因为Array#forEach对它传递的函数的返回值没有任何作用。

a.forEach(async u => {
    console.log('Deleting User: ' + u.id);
    await 3rdPartyApi.deleteUser({id: u.id});
});

这启动了一个计时器,甚至没有尝试等待它。

setTimeout(function () { console.log('Sleeping for 1 sec'); }, 1000);

将计时器拆分为一个函数,该函数返回在适当的时间内解析的promise(如果您使用的是Bluebird,则可以Promise.delay使用):

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

并将所有内容保存在一个async函数中,这样您就不会丢弃任何承诺:

function* chunk(array, size) {
    for (let i = 0; i < array.length;) {
        yield array.slice(i, i += size);
    }
}

const removeUsers = async () => {
    const users = await db.getUsers(); // returns 32 users.

    for (const a of chunk(users, 2)) {
        console.log(++counter);

        // Delete 2x users.
        for (const u of a) {
            console.log('Deleting User: ' + u.id);
            await ThirdPartyApi.deleteUser({id: u.id});
        }

        console.log('Sleeping for 1 sec');
        await delay(1000);
    }
};