Ending a Promise chain
Ending a Promise chain
我遇到一个关于未终止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);
});
});
};
requestAsync类方法是实际处理与ZWave服务器交互的方法。从概念上讲,在onOff()中,我试图打开或关闭由this.nodeNumber标识的特定灯光,然后返回该请求的结果。
onOff()是从Switch类方法调用的,表示一个特定的灯光,如下所示:
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;
} );
}
"return true"answers"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 );
} );
};
和
// 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;
} );
}
以下是警告文本:
警告:在处理程序中创建了promise,但未从中返回在ZWave.requestAsync(/home/mark/XmasLights/zWaveRequest.js:19:12)在ZWave.onOff(/home/mark/XmasLights/zWaveRequest.js:93:17)在onOff(/home/mark/XmasLights/switch.js:42:22)在updateCron(/home/mark/XmasLights/switch.js:80:18)每日更新(/home/mark/XmasLights/app.js:196:21)在/home/mark/XmasLights/app.js:134:58在processImmediate[as_immediateCallback](timers.js:383:17)
很抱歉警告的格式不正确,我似乎无法让stackoverflow正确地分隔行。
根据Bluebird文档,当您在promise范围内创建promise,但没有从该promise范围返回任何内容时,就会出现此警告。Bluebird检测到您在promise处理程序中创建了一个promise,但没有从该处理程序返回任何内容,该处理程序可能是一个未链接的promise,而它本应链接到其他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);
});
});
};
在哪里你最好避免反模式并这样做:
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');
});
};
没有必要在这里创建一个新的承诺,因为你已经有了一个可以直接返回的承诺。你可以在这里阅读更多关于避免使用反模式的信息。
另一个可能的问题是,您创建了一个return promise值,但不从方法this.onOff
返回它。您已经从.then()
处理程序中显式地执行了return true;
或return false;
,但您从未使用该返回值执行任何操作,因为没有后续的.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;
} );
}
我建议改变它来回报这样的承诺:
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;
} );
}
然后,将true
或false
返回的promise值提供给.onOff()
的调用者。或者,如果不需要获取这些返回值,那么可以删除return true
和return false
语句,这样就没有promise值。
这让我觉得是一个更普遍问题的具体例子:如何你从基于Promise的模型转向了传统的阻塞代码吗?
您不会为异步操作编写传统的阻塞代码。异步操作是异步的,永远不会是传统的阻塞代码。Promise为管理和协调异步操作提供了更多的结构,但您仍然必须以异步方式为它们编写代码。使用promise编写异步代码更容易。
JS语言正在添加更多的功能,如生成器和等待,您可以使用它们来帮助实现这一点。这里有一篇关于这个主题的短文:ES7异步函数。
- 使用promise和mongoose对文档进行排序
- 测试Angular Service解决错误回调中的promise
- 节点协同与生成器和Promise并行流量控制
- 根据是否解析了 Promise 从函数返回值
- 将一个方法转换为promise:Nodejs
- 函数在promise被解析后被调用,但Jasmine未通过测试.为什么?
- js promise没有正确关闭
- Angularjs使用“;这个“;promise内的关键字回调
- AngularJS和promise值在调用本地函数时的效果-未定义
- 在ES6 Promise中,我应该在解决/拒绝之前使用return吗
- 以同步方式获取Javascript Promise的值
- NodeJS和pg promise,捕获PostgreSQL异常
- AngularJS使用http进行promise处理
- Angular promise return"未定义的“;值.NET MVC
- Promise/A+ with chain then() 回调用例
- 减速器中的React/Redux、chain或promise
- Ending a Promise chain
- AngularJS : Seqential Promise chain
- Angularjs: chain promises返回一个promise而不是一个对象
- 在promise-chain中传递引用函数的值