考虑到我们想要在Node.js中执行一些需要一些时间才能完成的操作,比如说<?php require_once('admin_header.php'); ?>
<div class="container">
<?php echo validation_errors(); ?>
<div class="row">
<?php echo form_open('admin/store_article',['class'=>'form-horizontal']); ?>
<?php echo form_hidden('user_id', $this->session->userdata('user_id'));?>
<fieldset>
<legend>Add Article</legend>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label for="inputEmail" class="col-lg-4 control-label">Title</label>
<div class="col-lg-8">
<?php
$data = array(
'name' => 'title',
'class' => 'form-control',
'value' => set_value('title'),
'placeholder' => 'Username'
);
echo form_input($data);
?>
</div>
</div>
</div>
<div class="col-sm-6">
<?php echo form_error('title'); ?>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label for="inputPassword" class="col-lg-4 control-label">Article Body</label>
<div class="col-lg-8">
<?php
$data = array(
'name' => 'body',
'value' => set_value('body'),
'class' => 'form-control',
'placeholder' => 'Article Body',
);
echo form_textarea($data);
?>
</div>
</div>
</div>
<div class="col-sm-6">
<?php echo form_error('body'); ?>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<div class="col-lg-8 col-lg-offset-4">
<?php
$data = array(
'name' => 'reset',
'class' => 'btn btn-default',
'value' => 'Reset',
);
echo form_reset($data);
?>
<?php
$data = array(
'name' => 'submit',
'class' => 'btn btn-primary',
'value' => 'Submit',
);
echo form_submit($data);
?>
</div>
</div>
</div>
</div>
</fieldset>
</form>
</div>
</div>
<?php require_once('admin_footer.php'); ?>
。我们通常做的是传递一个类似的回调函数:
doHeavyWork()
现在,我想建立一个完成操作的限制时间。我想要的是,如果该操作的正常运行时间超过限制时间,该函数将终止并通知回调超出限制时间。
如何在Node.js中完成?
答案 0 :(得分:3)
您认为这可以通过简单的回调来实现,但我会为您说明问题
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)
})
&#13;
现在观看如果将3000
更改为超过5000
毫秒超时的值,会发生什么情况 - 例如,尝试10000
。您会看到callback
被调用两次。这个不好!除非你想用大量的垃圾来破坏你的功能,否则不容易修复。
如果我们使用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) }
)
&#13;
现在看看如果再次将3000
更改为10000
会发生什么。承诺&#34;回调&#34;只会被调用一次
最后,使用Promise.race
甚至可以更多地改进此代码。 Promise.race
将返回一个新的Promise,只要其中一个输入Promises结算或拒绝,它就会解析或拒绝。这非常适合我们的用例。
最重要的是,请注意超时逻辑如何与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) }
)
&#13;
在上面的代码示例中,将5000
的超时值更改为更短的内容,例如1000
,以查看错误的内容