承诺。然后连锁'无法设置未定义的属性'

时间:2017-11-09 11:17:57

标签: javascript node.js promise

我是承诺的新手,无法解决此语法问题。

在我的.then链中,我得到了这一部分。我有一个数组数组,并希望为数组中的一些对象添加一个新属性。在我这样做之前,我必须向googleDirection.directionRequest提出请求,这将解决新的承诺。但是在向对象添加属性时,对象是未定义的(我认为因为dbResult在嵌套的.then链之外)。我尝试了不同的方法,但无法解决这个问题。 希望有些人可以帮助我。

.then(function(dbResult){
    for(var i = 0; i < dbResult.length; i++){
      if(dbResult[i].length == 1){            
        var smallestValue = googleDirection.directionRequest(req.body.startlocation.latitude + "," + req.body.startlocation.longitude, dbResult[i][0].startLatitude + "," + dbResult[i][0].startLongitude,true,false)
        .then(function(distance){
          var values = [];
          for(var j = 0; j < distance.routes.length; j++){
            values.push(distance.routes[j].legs[0].distance.value);
          }
          return Math.min.apply(Math,values);
        })
        .then(function(value){
          return(value);
        })
        smallestValue.then(function(value){
          dbResult[i].tripStartToConstrStart = value;
        })
      }
    }
    return dbResult
  })
.then(function(dbResult){
    console.log(dbResult)       
  })

这是错误:

(node:8708) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: Cannot set property 'tripStartToConstrStart' of undefined
(node:8708) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): TypeError: Cannot set property 'tripStartToConstrStart' of undefined

2 个答案:

答案 0 :(得分:3)

您的错误原因称为“关闭循环变量”,这意味着当异步操作完成并尝试执行时

dbResult[i].tripStartToConstrStart = value;

i与[{1}}具有相同的价值(因为到那时dbResult.length循环已完成),fordbResult[dbResult.length]

正如评论者已经说过的那样,您可以使用undefined解决这个问题,但我认为使用let会更容易返回您需要等待的所有承诺(因为不等待承诺是你代码中的另一个大问题):

map

答案 1 :(得分:1)

那是因为异步任务,我总是在请求返回结果之前递增。

您可以在

中使用let i = 0

```

for(var i = 0; i < dbResult.length; i++){

```

或者您可以使用闭包来解决problem

想想这三个例子:

for (var i =0; i< 10;i++) {
  setTimeout(function(){
    console.log(i);
  },10)
}

for (let i =0; i< 10;i++) {
  setTimeout(function(){console.log(i)},10)
}

for(var i = 0; i < 10; i++){
  (function(j) {
    setTimeout(function() {
      console.log(j)
    }, 10);
  })(i);
}