【问题标题】:Changing callback into a promise chain将回调更改为承诺链
【发布时间】:2018-09-19 03:44:06
【问题描述】:

我试图开始使用承诺链(目前一直在使用回调),我想编辑这段代码:

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。忘记在帖子里补充了

我只是在学习承诺。我错过了什么?里面的代码几乎一模一样。

【问题讨论】:

    标签: javascript node.js asynchronous callback promise


    【解决方案1】:

    .then promises 中的函数最多可以有两个参数,必须是两个函数,第一个函数是当 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
    

    【讨论】:

      【解决方案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
          });
      

      【讨论】:

      • 这与我不工作的代码有何不同?我只是想找出我的错误
      • 查看您尝试的基于 Promise 的代码的第二行。您提供给then 的函数中有两个参数。你应该只有一个。
      • 从该函数中删除错误检查内容。错误检查应该在一个单独的函数中处理,要么在then(我的第二个例子)的第二个参数中,要么在catch(我的第三个例子)中
      【解决方案3】:

      then 只是在成功时调用,因此肯定没有错误:

       then((acc) => {
      

      【讨论】:

      • 未保存更改,控制台记录acc 会导致undefined。忘记在帖子中添加了
      • @alex3wielki 帐户可能还不存在?
      • 代码在同一个地方。帐户在顶部声明
      【解决方案4】:

      发生这种情况是因为函数“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);
      });
      

      【讨论】:

        猜你喜欢
        • 2018-05-04
        • 2016-06-15
        • 2019-05-05
        • 2023-03-26
        • 2023-01-27
        • 1970-01-01
        • 2015-07-02
        • 2016-06-18
        • 1970-01-01
        相关资源
        最近更新 更多