2015-01-27 2 views
0

나는 약속을 위해서 the 'Q' library을 사용하고 있습니다.결과를 반환하기위한 약속의 올바른 사용

var results = dbContext.query(userCert.conn, dbQuery.BuildQuery(query)); 

var models = []; 
if (!results.hasErr) { 
    for (var r in results.okPacket.results) { 
     var m = new model(results.okPacket.results[r]); 
     models.push(m); 
    } 
} 
userCert.conn.end(); // close db connection 

dbContext.query(...)에서 :

var $Q = require('Q'); 

function execQuery(connection, query) { 
    console.log("[backend][context] EXEC QUERY: " + query); 
    $Q.nfcall(connection.query, query) 
     .then(function (err, results) { 
      var ret = {}; 
      if (err) { 
       // log 
       var errPkt = getErrPacket(err); 
       console.log("QUERY ERROR[" + errPkt.errCode + ": " + 
       errPkt.errConst + "]: " + errPkt.errMessage); 
       ret = { 
        hasErr: true, 
        errPacket: errPkt 
       }; 
      } else { 
       ret = { 
        hasErr: false, 
        okPacket: { 
         resType: results.constructor.name, 
         resLength: results.length, 
         results: results 
        } 
       }; 
      } 

      // is this correct? 
      return function() { 
       return ret; 
      }; 
     }) 
     .then(function (ret) { 
      // how do I then return ret to the caller? 
     }) 
     .done(); 
} 

나는 길을 잃은 조금 해요 (가능한 경우)이 작업을 수행하는 다음

는 시나리오입니다. 콜백은 내 응용 프로그램의 하위 수준에서는 괜찮지 만 콜백 스파게티로 가득 찬 접시로 끝내기를 원하지 않았습니다.

+0

을 ... – dandavis

+0

@dandavis :'connection.query'는 데이터베이스 호출이고 비동기식입니다. – IAbstract

+0

그것은 당신이 무엇을 통과하는지에 달려 있습니다; 예 :'.then (alert)'는 함수가 반환 한 인수를 경고합니다. 문제를 혼란스럽게 만들면 좋은 답변을 얻은 것처럼 보입니다. – dandavis

답변

0

약속은 여전히 ​​콜백입니다. 그들은 코드의 실제 메커니즘을 변경하지 않습니다. 유일한 차이점은 콜백을 취소 할 수 있다는 약속입니다. 그러나 여전히 콜백을 사용하고 있습니다.

코드가 비동기 적으로 실행 중이기 때문에 호출자에게 값을 반환 할 수 없습니다. 약속의 유일한 차이점은 IN을 콜백으로 전달하는 대신 콜백을 전달하는 then이라는 메서드가있는 객체 (약속)를 반환한다는 것입니다. 발신자 후 바로 반환 약속을 사용할 수 있습니다

function execQuery(connection, query) { 
    console.log("[backend][context] EXEC QUERY: " + query); 
    return $Q.nfcall(connection.query, query) 
     .then(function(results) { 
      return { 
       hasErr: false, 
       okPacket: { 
        resType: results.constructor.name, 
        resLength: results.length, 
        results: results 
       } 
      }; 
     }) 
     .catch(function(err) { 
      // This doesn't necessarily mean a database error because 
      // all errors are caught here 
      if (false /* 
       TODO logic that checks if the err is not a database error 
       in which case you should just rethrow 
      */) { 
       throw err; 
      } 
      var errPkt = getErrPacket(err); 
      console.log("QUERY ERROR[" + errPkt.errCode + ": " + 
      errPkt.errConst + "]: " + errPkt.errMessage); 
      return { 
       hasErr: true, 
       errPacket: errPkt 
      }; 
     }); 
} 

: 당신은 그냥 호출자에게 약속을 반환 약속

+0

나는 당신이 요점을 놓치고 있다고 생각한다. 단지 함수의 이름을 지정함으로써 콜백을 취소 할 수 있기 때문에 확실히 유일한 차이는 아니다. – Esailija

+0

글쎄, 당신은 약속의 유무에 관계없이 그렇게 할 수 있습니다. 그래서 거기에는 차이점이 없습니다. 요점은 영업 이익이 약속이 당신이 약속을하는 것이 아닌 가치를 반환 할 수 있다고 가정하고 있다는 것입니다. – slebetman

+0

약속으로 할 수있는 모든 일은 약속없이 할 수 있습니다. 약속은 디자인 패턴 일뿐입니다. – slebetman

2

난 당신이 단순히 값을 반환 할 생각

dbContext.query(userCert.conn, dbQuery.BuildQuery(query)) 
    .then(function(results) { 
     // It is really weird to have to check for error in the success 
     // case but whatever floats your boat 
     if (!results.hasErr) { 
      var models = results.okPacket.results.map(function(result) { 
       return new model(result); 
      }); 
     } 
    }) 
    .finally(function() { 
     userCert.conn.end(); 
    }) 
    .done(); 
+0

이것은 유용 해 보입니다. 노드 -js 및 내장 된 기이 한 것들 중 일부를 여전히 학습합니다. 팁 주셔서 감사. – IAbstract

+0

이 코드는 그대로 구현되었지만 오류가 발생했습니다 : 'QUERY ERROR [undefined : Object # 에는'_implyConnect '메서드가 없습니다. : undefined'... :/다른 정보를보고 있습니다. – IAbstract

+0

@IAbstract 그렇기 때문에 데이터베이스 오류가 아닌 프로그래머 오류가 발생하는 경우에 대비하여 다시 검사를 구현해야합니다. 이것은'.done()'때문에 프로세스가 실패하게되고 스택 추적을 볼 수 있습니다 – Esailija