将回调更改为承诺链

时间:2018-04-09 17:04:00

标签: javascript node.js asynchronous callback promise

我试图开始使用promise chaining(到目前为止使用回调),我想编辑这段代码:

Account.findById(req.user._id,
    (err, acc) => {
        if (err) console.log(err);
        var r = req.body;
        acc.fullName = r.fullName;
        acc.displayname = r.username;
        acc.city = r.city;
        acc.province = r.province;
        acc.postalCode = r.postalCode;
        acc.phone = r.phone;
        acc.ageGroup = r.ageGroup;
        acc.education = r.education;
        acc.lookingForWork = r.lookingForWork;
        acc.employmentStatus = r.employmentStatus;
        acc.workingWithEOESC = r.workingWithEOESC;
        acc.resume = r.resume;
        acc.mainWorkExp = r.mainWorkExp;
        acc.save();
        res.redirect('/seeker');
    })

这就是我试图做的事情:

Account.findById(req.user._id)
    .then((err, acc) => {
        if (err) console.log(err);
        var r = req.body;
        acc.fullName = r.fullName;
        acc.displayname = r.username;
        acc.city = r.city;
        acc.province = r.province;
        acc.postalCode = r.postalCode;
        acc.phone = r.phone;
        acc.ageGroup = r.ageGroup;
        acc.education = r.education;
        acc.lookingForWork = r.lookingForWork;
        acc.employmentStatus = r.employmentStatus;
        acc.workingWithEOESC = r.workingWithEOESC;
        acc.resume = r.resume;
        acc.mainWorkExp = r.mainWorkExp;
        acc.save();
    })
    .catch(e => console.log(e))
    .then((acc) => {
        console.log(acc);
        res.redirect('/seeker');
    })
});

但是promise版本会引发TypeError: Cannot set property 'fullName' of undefined错误。

未保存更改,控制台记录acc会导致undefined。忘了在帖子中添加

我只是在学习承诺。我错过了什么?内部代码几乎完全相同。

4 个答案:

答案 0 :(得分:2)

promises中的

.then函数可以使用maxiumum两个参数,它必须是两个函数,第一个函数是promise完全填充,而第二个函数是promise被拒绝的时候,或者你只能传入一个函数.then并使用.catch来处理任何类型的错误或被拒绝的承诺

var f1 = acc => console.log(acc); // logs out the acc object;
var f2 = err => console.log(err); // logs out error while executing the promise

.then(f1,f2); // when you do this there is no need for a catch block

// or

.then( acc => {
    console.log(acc) // logs out the acc object
 }).catch( err => console.log(err) ) //logs out the error


 // if you need to handle another value

 .then( acc => {
      console.log(acc);
      return acc.save(); //lets say acc.save() returns an object
  }).then( acc => console.log(acc) ); // the value of acc.save() is passed down to the next `.then` block

答案 1 :(得分:2)

基于回调的API有一个共同的约定,即使用回调函数的第一个参数来指示失败。 Promise不需要这样的约定,因为它们有内置的处理失败的方法,所以你需要只操作第一个参数,而不是第二个参数。第二个参数将是undefined,导致您看到错误。

大多数情况下,当您将基于回调的代码转换为基于承诺的代码时,您希望将此模式用作基本指南:

// Callback-based:
asyncFn((err, result) => {
    if (err) {
        // handle failure
    } else {
        // handle success
    }
});


// Promise-based equivalent:
asyncFnPromise()
    .then((result) => {
        // handle success
    }, (err) => {
        // handle failure
    });


// Alternative promised-based:
asyncFnPromise()
    .then((result) => {
        // handle success.
        // Note that unlike the above, any errors thrown here will trigger
        // the `catch` handler below, in addition to actual asyncFnPromise
        // failures.
    })
    .catch((err) => {
        // handle failure
    });

答案 2 :(得分:0)

then只是被称为成功,因此肯定没有错误:

 then((acc) => {

答案 3 :(得分:0)

这是因为函数'findById'可能没有返回'promise'而只是返回一些响应。你需要在findById函数中创建一个'promise对象'并返回它。

findById (){
  let promise = new Promise((resolve, reject) => {  
  Suppose results is yield from some async task, so when
  //wanted results occured
    resolve(value);

  //unwanted result occured
    reject(new Error('Something happened!'));

  return promise;
}



findById.then(response => {
   console.log(response);
}, error => {
   console.log(error);
});