如果未能及时完成,NodeJS将超时

一定时间后如何使承诺超时?我知道Q有一个Promise超时,但是我使用的是本机NodeJS Promise,它们没有.timeout函数。

我是否想念一个或包裹不同的包裹?

或者,下面的实现在不占用内存的情况下是否很好,实际上按预期方式工作?

还可以以某种方式将其包装到全局中,以便将其用于我创建的每个promise,而不必重复setTimeout和clearTimeout代码吗?

function run() {

logger.info('DoNothingController working on process id {0}...'.format(process.pid));

myPromise(4000)

.then(function() {

logger.info('Successful!');

})

.catch(function(error) {

logger.error('Failed! ' + error);

});

}

function myPromise(ms) {

return new Promise(function(resolve, reject) {

var hasValueReturned;

var promiseTimeout = setTimeout(function() {

if (!hasValueReturned) {

reject('Promise timed out after ' + ms + ' ms');

}

}, ms);

// Do something, for example for testing purposes

setTimeout(function() {

resolve();

clearTimeout(promiseTimeout);

}, ms - 2000);

});

}

谢谢!

回答:

本机JavaScript承诺没有任何超时机制。

有关您的实现的问题可能更适合http://codereview.stackexchange.com,但有几点注意事项:

  1. 您没有提供在诺言中实际做任何事情的方法,并且

  2. 由于计划了一次计时器,因此不需要clearTimeoutsetTimeout回调中进行setTimeout

  3. 由于承诺一旦被解决/被拒绝,就无法被解决/被拒绝,因此您不需要进行检查。

所以也许遵循以下思路:

function myPromise(ms, callback) {

return new Promise(function(resolve, reject) {

// Set up the real work

callback(resolve, reject);

// Set up the timeout

setTimeout(function() {

reject('Promise timed out after ' + ms + ' ms');

}, ms);

});

}

像这样使用:

myPromise(2000, function(resolve, reject) {

// Real work is here

});

(或者您 希望它稍微复杂一些,请参见下面的更新。)

我会稍微担心以下事实,即语义会稍有不同(no new,而您确实使用newPromise构造函数),因此可以进行调整。

当然,另一个问题是,在大多数情况下,您不想构建新的Promise,因此无法使用以上内容。大多数时候,您已经有一个承诺(上一次then通话的结果,等等)。但是,对于真正要构建新承诺的情况,可以使用上述类似方法。

您可以new通过子类化处理Promise

class MyPromise extends Promise {

constructor(ms, callback) {

// We need to support being called with no milliseconds

// value, because the various Promise methods (`then` and

// such) correctly call the subclass constructor when

// building the new promises they return.

// This code to do it is ugly, could use some love, but it

// gives you the idea.

let haveTimeout = typeof ms === "number" && typeof callback === "function";

let init = haveTimeout ? callback : ms;

super((resolve, reject) => {

init(resolve, reject);

if (haveTimeout) {

setTimeout(() => {

reject("Timed out");

}, ms);

}

});

}

}

用法:

let p = new MyPromise(300, function(resolve, reject) {

// ...

});

p.then(result => {

})

.catch(error => {

});

// Uses var instead of let and non-arrow functions to try to be

// compatible with browsers that aren't quite fully ES6 yet, but

// do have promises...

(function() {

"use strict";

class MyPromise extends Promise {

constructor(ms, callback) {

var haveTimeout = typeof ms === "number" && typeof callback === "function";

var init = haveTimeout ? callback : ms;

super(function(resolve, reject) {

init(resolve, reject);

if (haveTimeout) {

setTimeout(function() {

reject("Timed out");

}, ms);

}

});

}

}

var p = new MyPromise(100, function(resolve, reject) {

// We never resolve/reject, so we test the timeout

});

p.then(function(result) {

snippet.log("Resolved: " + result);

}).catch(function(reject) {

snippet.log("Rejected: " + reject);

});

})();

<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->

<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>


reject计时器到期时,即使回调调用resolvereject第一次调用,这两者都将调用。这很好,承诺的结算状态不能一旦它的设置改变,该规范定义来电resolvereject上一个已经解决的不产生错误的DO-

空话的承诺。

但是,如果麻烦您了,您可以把resolve和包装起来reject。这里的myPromise这样做的方式:

function myPromise(ms, callback) {

return new Promise(function(resolve, reject) {

// Set up the timeout

let timer = setTimeout(function() {

reject('Promise timed out after ' + ms + ' ms');

}, ms);

let cancelTimer = _ => {

if (timer) {

clearTimeout(timer);

timer = 0;

}

};

// Set up the real work

callback(

value => {

cancelTimer();

resolve(value);

},

error => {

cancelTimer();

reject(error);

}

);

});

}

您可以旋转约18种不同的方式,但是基本概念是,resolve并且reject我们通过收到的promise执行程序是清除计时器的包装器。

,这会创建不需要的函数和额外的函数调用。规范明确了已解决诺言时的解决功能。他们很早就退出了。

以上是 如果未能及时完成,NodeJS将超时 的全部内容, 来源链接: utcz.com/qa/405123.html

回到顶部