如何使用 Q 将事件侦听器转换为 Promise
How to convert an event listener to a promise using Q
大家好,我是 nodejs 的新手,我正在尝试学习 promises。我正在尝试实现一种菜单,该菜单将根据用户输入执行某些功能。这是我正在使用的代码:
var q = require('q');
var readline = require('readline-sync');
function createNewPreset(){
var deferred = q.defer();
var preset = {
"name" : undefined,
"unit" : undefined,
"interval" : undefined,
"files" : [],
}
deferred.resolve(preset);
return deferred.promise;
}
function addPreset(){
console.log("adding");
var deferred = q.defer();
createNewPreset()
.then(function(){
console.log("Gettind input in addPreset");
})
.then(getUserInput)
.then(function(data){
console.log("Adding data" + data);
});
}
function getUserInput(){
var deferred = q.defer();
var stdin = process.stdin;
stdin.resume();
stdin.once('data', function(data){
data = data.toString().trim()
if(data.length > 20){
var err = new Error("The entered preset name is too long");
deferred.reject(err);
}
else{
deferred.resolve(data);
}
});
return deferred.promise;
}
function processChoice(input){
var deferred = q.defer();
var error = undefined;
var func;
switch(input){
case "a":
func = addPreset;
break;
case "q":
func = function(){
process.exit();
}
break;
default:
error = new Error("Invalid menu option entered.");
deferred.reject(error);
break;
}
deferred.resolve(func);
return deferred.promise;
}
function prompt(){
var stdout = process.stdout;
//indicates that prompt is being executed
stdout.write("(tic): ");
console.log("Waiting for input");
getUserInput()
.then(processChoice)
.then(function(func){ func(); })
.catch(function(err) {console.log(err)})
.then(prompt);
}
prompt();
我认为问题出在 getUserInput()
和 addPreset()
与事件侦听器之间。我希望 promise 链仅在事件侦听器被激活后才继续,但老实说我不确定该怎么做。
这是我的结果:
(tic): Waiting for input
a
adding
Gettind input in addPreset
(tic): Waiting for input
A
Adding dataA
[Error: Invalid menu option entered.]
(tic): Waiting for input
我想让链在继续之前等待事件侦听器执行。有什么办法可以做到这一点?
您的代码中存在一些错误
排名不分先后
.then(function(func){ func(); })
应该是 .then(function(func){ return func(); })
- 因为 func return 是一个你想要等待的承诺,没有 return
那里的过程在 [= 之前继续进行14=] 已解决
- 在几个函数中你创建了一个 deferred 但没有使用它 - 删除了那些
- 其他地方你创建一个你解决的延迟 return,只是 return 一个
q.resolve()
下面的代码根本没有使用 q
promises,我已经改为原生 Promise
来测试我的答案 - 但转换回 [=16= 应该很简单]
function createNewPreset(){
return Promise.resolve({
"name" : undefined,
"unit" : undefined,
"interval" : undefined,
"files" : [],
});
}
function addPreset(){
console.log("adding");
return createNewPreset()
.then(function(){
console.log("Gettind input in addPreset");
})
.then(getUserInput)
.then(function(data){
console.log("Adding data " + data);
});
}
function getUserInput(){
return new Promise(function(resolve, reject) {
var stdin = process.stdin;
stdin.resume();
stdin.once('data', function(data){
data = data.toString().trim()
if(data.length > 20){
var err = new Error("The entered preset name is too long");
reject(err);
}
else{
resolve(data);
}
});
});
}
function processChoice(input){
return new Promise(function(resolve, reject) {
var error = undefined;
var func;
switch(input){
case "a":
func = addPreset;
break;
case "q":
func = function(){
process.exit();
}
break;
default:
error = new Error("Invalid menu option entered.");
reject(error);
break;
}
resolve(func);
});
}
function prompt(){
var stdout = process.stdout;
//indicates that prompt is being executed
stdout.write("(tic): ");
console.log("PROMPT waiting for input");
getUserInput()
.then(processChoice)
.then(function(func){ return func(); })
.catch(function(err) {console.log(err)})
.then(prompt);
}
prompt();
大家好,我是 nodejs 的新手,我正在尝试学习 promises。我正在尝试实现一种菜单,该菜单将根据用户输入执行某些功能。这是我正在使用的代码:
var q = require('q');
var readline = require('readline-sync');
function createNewPreset(){
var deferred = q.defer();
var preset = {
"name" : undefined,
"unit" : undefined,
"interval" : undefined,
"files" : [],
}
deferred.resolve(preset);
return deferred.promise;
}
function addPreset(){
console.log("adding");
var deferred = q.defer();
createNewPreset()
.then(function(){
console.log("Gettind input in addPreset");
})
.then(getUserInput)
.then(function(data){
console.log("Adding data" + data);
});
}
function getUserInput(){
var deferred = q.defer();
var stdin = process.stdin;
stdin.resume();
stdin.once('data', function(data){
data = data.toString().trim()
if(data.length > 20){
var err = new Error("The entered preset name is too long");
deferred.reject(err);
}
else{
deferred.resolve(data);
}
});
return deferred.promise;
}
function processChoice(input){
var deferred = q.defer();
var error = undefined;
var func;
switch(input){
case "a":
func = addPreset;
break;
case "q":
func = function(){
process.exit();
}
break;
default:
error = new Error("Invalid menu option entered.");
deferred.reject(error);
break;
}
deferred.resolve(func);
return deferred.promise;
}
function prompt(){
var stdout = process.stdout;
//indicates that prompt is being executed
stdout.write("(tic): ");
console.log("Waiting for input");
getUserInput()
.then(processChoice)
.then(function(func){ func(); })
.catch(function(err) {console.log(err)})
.then(prompt);
}
prompt();
我认为问题出在 getUserInput()
和 addPreset()
与事件侦听器之间。我希望 promise 链仅在事件侦听器被激活后才继续,但老实说我不确定该怎么做。
这是我的结果:
(tic): Waiting for input
a
adding
Gettind input in addPreset
(tic): Waiting for input
A
Adding dataA
[Error: Invalid menu option entered.]
(tic): Waiting for input
我想让链在继续之前等待事件侦听器执行。有什么办法可以做到这一点?
您的代码中存在一些错误
排名不分先后
.then(function(func){ func(); })
应该是.then(function(func){ return func(); })
- 因为 func return 是一个你想要等待的承诺,没有return
那里的过程在 [= 之前继续进行14=] 已解决- 在几个函数中你创建了一个 deferred 但没有使用它 - 删除了那些
- 其他地方你创建一个你解决的延迟 return,只是 return 一个
q.resolve()
下面的代码根本没有使用 q
promises,我已经改为原生 Promise
来测试我的答案 - 但转换回 [=16= 应该很简单]
function createNewPreset(){
return Promise.resolve({
"name" : undefined,
"unit" : undefined,
"interval" : undefined,
"files" : [],
});
}
function addPreset(){
console.log("adding");
return createNewPreset()
.then(function(){
console.log("Gettind input in addPreset");
})
.then(getUserInput)
.then(function(data){
console.log("Adding data " + data);
});
}
function getUserInput(){
return new Promise(function(resolve, reject) {
var stdin = process.stdin;
stdin.resume();
stdin.once('data', function(data){
data = data.toString().trim()
if(data.length > 20){
var err = new Error("The entered preset name is too long");
reject(err);
}
else{
resolve(data);
}
});
});
}
function processChoice(input){
return new Promise(function(resolve, reject) {
var error = undefined;
var func;
switch(input){
case "a":
func = addPreset;
break;
case "q":
func = function(){
process.exit();
}
break;
default:
error = new Error("Invalid menu option entered.");
reject(error);
break;
}
resolve(func);
});
}
function prompt(){
var stdout = process.stdout;
//indicates that prompt is being executed
stdout.write("(tic): ");
console.log("PROMPT waiting for input");
getUserInput()
.then(processChoice)
.then(function(func){ return func(); })
.catch(function(err) {console.log(err)})
.then(prompt);
}
prompt();