考虑一下,我们想要在 Node.js 中执行一些需要一些时间才能完成的操作,例如 doHeavyWork()
。我们通常做的是传递一个回调函数,如下所示:
doHeavyWork(params, callbackFunction);
现在,我想为该操作的完成设定一个限制时间。我想要的是,如果该操作的正常运行时间超过限制时间,该函数将终止并通知回调已超出限制时间。
如何在 Node.js 中实现这一点?
最佳答案
您可能认为通过简单的回调就可以做到这一点,但我将向您说明一个问题
function doHeavyWork(params, callback) {
// set the timeout
var timeout = setTimeout(callback, 5000, Error('timeout'))
// some debug message
console.log('Please wait...')
// begin heavy work
// we sill simulate heavy work with setTimeout here
setTimeout(function() {
// if the function completed in time, clear the timeout
clearTimeout(timeout)
// callback without error
callback(null, 'done')
}, 3000)
}
// check to see it work
doHeavyWork('some params', function(err, res) {
if (err)
throw error
else
console.log(res)
})
现在观察如果将 3000
更改为超过 5000
毫秒超时的值,会发生什么情况 - 例如,尝试 10000
。您将看到回调
被调用两次。不是很好!除非你想用大量垃圾弄乱你的函数,否则修复起来并不容易。
如果我们使用 Promise,我们可以很容易地解决这个问题
function doHeavyWork(params) {
return new Promise(function(resolve, reject) {
// set the timeout
var timeout = setTimeout(reject, 5000, Error('timeout'))
// some debug message
console.log('Please wait...')
// begin heavy work
// we sill simulate heavy work with setTimeout here
setTimeout(function() {
// if the function completed in time, clear the timeout
clearTimeout(timeout)
// callback without error
resolve('done')
}, 3000)
})
}
// check to see it work
doHeavyWork('some params').then(
function(res) { console.log(res) },
function(err) { console.log(err.message) }
)
现在看看如果您再次将 3000
更改为 10000
会发生什么。 Promise“回调”只会被调用一次
最后,甚至可以使用 Promise.race 进一步改进此代码。 Promise.race
将返回一个新的 Promise,一旦输入 Promise 之一解析或拒绝,该 Promise 就会解析或拒绝。这非常适合我们的用例。
最重要的是,请注意超时逻辑如何与 doHeavyWork
耦合。这可以使您的功能保持干净且井井有条。
function doHeavyWork(params) {
return new Promise(function(resolve, reject) {
// some debug message
console.log('Please wait...')
// begin heavy work
// we sill simulate heavy work with setTimeout here
setTimeout(resolve, 3000, 'done')
})
}
function timeout(ms) {
return new Promise(function(resolve, reject) {
setTimeout(reject, ms, Error('timeout'))
})
}
// using Promise.race
Promise.race([
timeout(5000),
doHeavyWork('some params')
]).then(
function(res) { console.log(res) },
function(err) { console.log(err.message) }
)
在上面的代码示例中,将 5000
的超时值更改为更短的值,例如 1000
以查看错误情况
关于javascript - 如果超过某个限制时间,如何在 Node.js 中完成一项操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38407373/