【问题标题】:Cannot read property 'then' of undefined with Promise无法使用 Promise 读取未定义的属性“then”
【发布时间】:2018-01-17 11:23:01
【问题描述】:
function recursiveAsyncReadLine(){
    rl.question("name : ", function(answer) {
        if(answer==="exit"){
            rl.close();
        }
        var kitty = new Kitten({name : answer});
        kitty.save(function(err, kitty){
            if(err){
                throw err;
            }
            kitty.speak();
            Kitten.find(function(err, kittens){
                if(err){
                    throw err;
                }
                console.log(kittens);
                recursiveAsyncReadLine();
            });
        });
    });
}

我尝试用 promise 更改上面的代码。

function recursiveAsyncReadLine(){
    rl.question("name: ")
    .then((answer)=>{
        if(answer==="exit"){
            rl.close();
        }
        var kitty = new Kitten({name : answer});
        return kitty.save();
    })
    .then((kitty)=>{
        kitty.speak();
        return Kitten.find();
    })
    .then((kittens)=>{
        console.log(kittens);
        recursiveAsyncReadLine();           
    })
    .catch((err)=>{
        throw err;
    });
}

但它不适用于消息

TypeError: 无法读取未定义的属性 'then'

错误发生在第一个“then”语句中。

我不确定我是否正确理解了 Promise。我哪里做错了?

【问题讨论】:

  • question() 返回什么?
  • question 是如何定义的?
  • question() 来自 readline.createInterface。抱歉错过了!
  • rl.question 是一个内置的节点方法,但它不返回 Promise。不能使用then 链接。这是一个相关的问题stackoverflow.com/questions/42080551/…
  • Promise 链是否至少需要一个 Promise 对象?

标签: javascript


【解决方案1】:

你误解了承诺。您的 r1.question 函数目前不返回承诺。它宁愿接受一个回调函数,然后你继续异步执行

为了保证它,您可以为 r1.question 创建一个包装函数,如下所示:---

var promisifiedr1 = new Promise(function(resolve, reject){
    rl.question("name: ", function(answer){
        resolve(answer);
    })
});

promisifiedr1.then((answer)=>{
    if(answer==="exit"){
        rl.close();
    }

    var promisifiedkitty = new Promise(function(resolve, reject){
        var kitty = new Kitten({name : answer});
        kitty.save(function(err, kitty){
        if(err){
            throw err;
        }
        resolve(kitty);
    });

    promisifiedkitty.then((kitty)=>{
       kitty.speak();
       return Kitten.find();
    })
    .then((kittens)=>{
       console.log(kittens);
       recursiveAsyncReadLine();           
    })
    .catch((err)=>{
        throw err;
    });
});

【讨论】:

  • 我误会了……谢谢!
【解决方案2】:

看起来question() 没有返回承诺,而是会调用回调。在这种情况下,您可以使用promisify 作为包装器来获得承诺。

const util = require('util');

function recursiveAsyncReadLine(){
    questionPromise = util.promisify(r1.question);
    questionPromise("name: ")
    .then((answer)=>{
        if(answer==="exit"){
            rl.close();
        }
        var kitty = new Kitten({name : answer});
        return kitty.save();
    })
    .then((kitty)=>{
        kitty.speak();
        return Kitten.find();
    })
    .then((kittens)=>{
        console.log(kittens);
        recursiveAsyncReadLine();           
    })
    .catch((err)=>{
        throw err;
    });
}

【讨论】:

  • 我必须更新我的 nodejs 才能使用该功能。无论如何感谢方便的功能!
猜你喜欢
  • 2014-11-26
  • 2018-01-15
  • 2018-06-02
  • 1970-01-01
  • 2017-04-21
  • 2019-08-19
  • 2016-10-23
  • 2014-09-07
相关资源
最近更新 更多