Mar*_*ert 7 javascript node.js promise
我正在遇到一个关于未终止的Promise链的Promise警告('一个承诺是在一个处理程序中创建但是没有从它返回').我是Promises的新手,怀疑我不应该使用非事件驱动的思维.但我不知道该怎么办.这都在nodejs项目中.
我正在与ZWave服务器交互以打开和关闭灯.该交互采取以下形式:向控制ZWave网络的服务器发出http请求.我正在使用Promises,因为通过http进行交互的异步性质.
在我的程序的一个级别,我定义了以下类方法:
ZWave.prototype.onOff = function (nodeNumber, turnOn) {
var self = this;
var level = turnOn ? 255 : 0;
return new Promise(function (resolve, reject) {
self.requestAsync(sprintf('/Run/devices[%d].instances[0].commandClasses[0x20].Set(%d)', nodeNumber, level))
.then(function (value) {
resolve(value == 'null');
})
.catch(function (error) {
reject(error);
});
});
Run Code Online (Sandbox Code Playgroud)
};
requestAsync类方法实际上是处理与ZWave服务器交互的方法.从概念上讲,在onOff()中,我试图打开或关闭由this.nodeNumber标识的特定灯光,然后返回该请求的结果.
从Switch类方法调用onOff(),表示特定的灯光,如下所示:
this.onOff = function( turnOn ) {
var state = turnOn ? 'ON' : 'OFF';
var self = this;
zWave.onOff( this.nodeNumber, turnOn )
.then( function() {
winston.info( sprintf( '%s: turned %s', self.displayName, state ) );
return true;
} )
.catch( function( error ) {
winston.info( sprintf( '%s: error while turning %s => %s', self.displayName, state, error ) );
return false;
} );
}
Run Code Online (Sandbox Code Playgroud)
'return true'和'return false'语句是我尝试结束Promise链.但它不起作用,我仍然收到警告.
这让我觉得这是一个更普遍的问题的具体例子:你如何从基于Promise的模型转变为传统的阻塞代码?
编辑
回答评论中的几个问题......
我正在使用蓝鸟.
zWave.onOff()返回一个promise.
Switch.onOff()和zWave.onOff()是不同类中的不同函数.
所有代码都是javascript.
编辑2
我相信我已经实现了jfriend00的建议,虽然我在zWave.onOff()函数中包含了一个.catch()处理程序,但我仍然得到相同的未处理的promise错误:
ZWave.prototype.onOff = function (nodeNumber, turnOn) {
var self = this;
var level = turnOn ? 255 : 0;
return self.requestAsync( sprintf( '/Run/devices[%d].instances[0].commandClasses[0x20].Set(%d)', nodeNumber, level ) )
.then( function( value ) {
resolve( value == 'null' );
} )
.catch( function( error ) {
reject( error );
} );
};
Run Code Online (Sandbox Code Playgroud)
和
// function inside Switch class
this.onOff = function( turnOn ) {
var state = turnOn ? 'ON' : 'OFF';
var self = this;
return zWave.onOff( this.nodeNumber, turnOn ).reflect()
.then( function() {
winston.info( sprintf( '%s: turned %s', self.displayName, state ) );
return true;
} )
.catch( function( error ) {
winston.info( sprintf( '%s: error while turning %s => %s', self.displayName, state, error ) );
return false;
} );
}
Run Code Online (Sandbox Code Playgroud)
以下是警告的内容:
警告:在ZWave.onOff(/home/mark/XmasLights/zWaveRequest.js)的ZWave.requestAsync(/home/mark/XmasLights/zWaveRequest.js:19:12)中,在处理程序中创建了一个承诺但未从它返回. :93:17)onOff(/home/mark/XmasLights/switch.js:42:22)at updateCron(/home/mark/XmasLights/switch.js:80:18)dailyUpdate(/ home/mark/XmasLights) /app.js:196:21)athome/mark/XmasLights/app.js:134:58 at processImmediate [as _immediateCallback](timers.js:383:17)
对于警告的格式化运行很抱歉,我似乎无法使用stackoverflow正确分隔行.
根据Bluebird文档,当您在promise范围内创建promise时会发生此警告,但您不会从该Promise范围返回任何内容.Bluebird检测到你在promise处理程序中创建了一个promise,但是没有从该处理程序返回任何东西,当它应该链接到其他promises时,它可能是一个未链接的promise.你可以在这里阅读他们对这个问题的看法.
在您公开的代码中,您没有显示任何类似Bluebird在其文档中显示的示例,但我猜这里有一个问题:
ZWave.prototype.onOff = function (nodeNumber, turnOn) {
var self = this;
var level = turnOn ? 255 : 0;
return new Promise(function (resolve, reject) {
self.requestAsync(sprintf('/Run/devices[%d].instances[0].commandClasses[0x20].Set(%d)', nodeNumber, level)).then(function (value) {
resolve(value == 'null');
}).catch(function (error) {
reject(error);
});
});
};
Run Code Online (Sandbox Code Playgroud)
你最好避免反模式并做到这一点:
ZWave.prototype.onOff = function (nodeNumber, turnOn) {
var level = turnOn ? 255 : 0;
return this.requestAsync(sprintf('/Run/devices[%d].instances[0].commandClasses[0x20].Set(%d)', nodeNumber, level)).then(function (value) {
return(value == 'null');
});
};
Run Code Online (Sandbox Code Playgroud)
这里没有必要创建一个新的承诺,因为你已经有一个你可以返回的承诺.您可以阅读有关避免使用此处使用的反模式类型的更多信息.
而且,另一个可能的问题是,您可以在其中创建返回承诺值,但不要从方法返回它this.onOff.你已经明确地完成了一个return true;或者return false;你的.then()处理程序,但是你永远不会对该返回值做任何事情,因为没有后续的.then()处理程序,并且不返回promise本身.
this.onOff = function( turnOn ) {
var state = turnOn ? 'ON' : 'OFF';
var self = this;
zWave.onOff( this.nodeNumber, turnOn )
.then( function() {
winston.info( sprintf( '%s: turned %s', self.displayName, state ) );
return true;
} )
.catch( function( error ) {
winston.info( sprintf( '%s: error while turning %s => %s', self.displayName, state, error ) );
return false;
} );
}
Run Code Online (Sandbox Code Playgroud)
我建议改变它以返回这样的承诺:
this.onOff = function( turnOn ) {
var state = turnOn ? 'ON' : 'OFF';
var self = this;
// ===== add return statement here
return zWave.onOff( this.nodeNumber, turnOn )
.then( function() {
winston.info( sprintf( '%s: turned %s', self.displayName, state ) );
return true;
} )
.catch( function( error ) {
winston.info( sprintf( '%s: error while turning %s => %s', self.displayName, state, error ) );
return false;
} );
}
Run Code Online (Sandbox Code Playgroud)
然后,它向调用者提供true或false返回的promise值.onOff().或者,如果您不需要获取这些返回的值,那么您可以删除return true和return false语句,因此没有promise值.
这让我觉得这是一个更普遍的问题的具体例子:你如何从基于Promise的模型转变为传统的阻塞代码?
您不会为异步操作编写传统的阻止代码.异步操作是异步的,永远不会是传统的阻塞代码.Promise为管理和协调异步操作提供了更多的结构,但您仍然必须以异步方式为它们编写代码.使用promises编写异步代码更容易.
JS语言正在添加更多功能,例如生成器和等待,您可以使用它们来帮助解决这个问题.这是关于该主题的简短文章:ES7异步函数.
| 归档时间: |
|
| 查看次数: |
6635 次 |
| 最近记录: |