如何使用Q将事件监听器转换为promise



大家好,我是nodejs的新手,我正在努力学习promise。我正在尝试实现一种菜单,它将根据用户输入执行某些功能。这是我正在使用的代码:

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()以及事件侦听器上。我希望只有在事件监听器被激活后,承诺链才能继续,但老实说,我不知道如何做到这一点。

以下是我的结果:

(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返回一个您想要等待的promise,如果没有return,则在addPreset解析之前,该过程仍在继续
  • 在几个函数中,您创建了一个deferred而不使用它-删除了
  • 在您创建的其他地方,您解决并返回一个延迟,只需返回一个q.resolve()

下面的代码根本不使用q承诺,我已经改为原生Promise来测试我的答案,但转换回q 应该很简单

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();

相关内容

  • 没有找到相关文章

最新更新