我正在为个人需求开发一个控制台脚本。我需要能够暂停更长的时间,但是,根据我的研究,Node.js没有办法根据需要停止。一段时间后,读取用户信息变得越来越困难了……我已经看到了一些代码,但我相信他们必须有其他的代码在他们的工作,如:
setTimeout(function() {
}, 3000);
但是,我需要这行代码之后的所有内容在一段时间之后执行。
例如,
// start of code
console.log('Welcome to my console,');
some-wait-code-here-for-ten-seconds...
console.log('Blah blah blah blah extra-blah');
// end of code
我还见过
yield sleep(2000);
但是Node.js不能识别这个。
我怎样才能实现这种延长的暂停?
为了在javascript中“等待”,使用承诺是一种方法,正如上面的答案所示。
那么如何使用它呢?
下面是一个简单的例子,一个5秒的子进程以非阻塞的方式为一个4秒的主进程排队参数。
const wait = (seconds) =>
new Promise(resolve =>
setTimeout(() =>
resolve(true), seconds * 1000))
const process = async (items, prepTask, mainTask) => {
const queue = [];
let done = false;
items.forEach((item, i) => {
prepTask(item).then(() => {
queue.push(item);
if (i == items.length -1) {
done = true;
}
})
})
while (!done || queue.length) {
if (queue.length) {
const workload = queue.shift();
await mainTask(workload)
} else {
console.log('waiting for subtask to queue')
await wait(1);
}
}
}
// Usage Example
const ids = [1,2,3,4,5,6,7,8,9,10];
const prepTask = async (id) => {
await wait(id * 5)
return id * 5;
}
const mainTask = async (workload) => {
console.log('excuting workload: ', workload);
const result = await wait(4);
return { workload, result }
}
process(ids, prepTask, mainTask)
.then(() => console.log('done'))
有了ES6支持的promise,我们可以在没有任何第三方帮助的情况下使用它们。
const sleep = (seconds) => {
return new Promise((resolve, reject) => {
setTimeout(resolve, (seconds * 1000));
});
};
// We are not using `reject` anywhere, but it is good to
// stick to standard signature.
然后这样使用它:
const waitThenDo(howLong, doWhat) => {
return sleep(howLong).then(doWhat);
};
注意,doWhat函数变成了新的Promise(…)中的解析回调函数。
还要注意,这是异步睡眠。它不会阻塞事件循环。如果你需要阻塞睡眠,使用这个库,它在c++绑定的帮助下实现了阻塞睡眠。(尽管在Node中像异步环境一样需要阻塞睡眠的情况很少。)
https://github.com/erikdubbelboer/node-sleep
let co = require('co');
const sleep = ms => new Promise(res => setTimeout(res, ms));
co(function*() {
console.log('Welcome to My Console,');
yield sleep(3000);
console.log('Blah blah blah blah extra-blah');
});
This code above is the side effect of the solving Javascript's asynchronous callback hell problem. This is also the reason I think that makes Javascript a useful language in the backend. Actually this is the most exciting improvement introduced to modern Javascript in my opinion. To fully understand how it works, how generator works needs to be fully understood. The function keyword followed by a * is called a generator function in modern Javascript. The npm package co provided a runner function to run a generator.
本质上,生成器函数提供了一种使用yield关键字暂停函数执行的方法,同时,生成器函数中的yield使生成器内部和调用者之间交换信息成为可能。这为调用方提供了一种机制,可以从异步调用的promise中提取数据,并将已解析的数据传递回生成器。实际上,它使异步调用同步化。