2017-05-22 3 views
-3

다음 질문은 인터뷰에서 가져온 것입니다. 일부 부품을 해결할 수 있었지만 걸렸습니다.버그 수정! (동기 함수 내에서 비동기 함수를 호출하는 방법)

다음 코드에서 버그를 수정했습니다. DataContainer은 데이터베이스에서 가져온 데이터의 캐시를 제공하는 데이터베이스 주위의 래퍼입니다. DbConnection를 통해 데이터베이스에서 데이터를 가져해야를 가져 호출

. 가져 오기가 성공하면 을 반환해야합니다.; 그렇지 않으면 false을 반환해야합니다. getData를 호출하면 데이터가 아직 페치되지 않은 경우 캐싱 된 데이터가 반환되거나 예외가 throw됩니다.

function DataContainer(connectionString) { 
    var dataFetched = false; 
    var dbConnection = DbConnection(connectionString); 
} 

DataContainer.prototype.getData = function() { 
    if (!this.dataFetched) 
    throw "Data not fetched!"; 
    return this.data; 
} 

DataContainer.prototype.fetch = function() { 
    this.dbConnection.getAllData(function (err, result) { 
    if (err) { 
     delete this.data; 
     this.dataFetched = false; 
     return false; 
    } else { 
     this.data = result; 
     this.dataFetched = true; 
     return true; 
    } 
    }); 
} 

// Mock of DbConnection for testing purposes: 
function DbConnection(connectionString) { } 

DbConnection.prototype.getAllData = function (callback) { 
    callback(null, [1, 2, 3]); 
} 

//Expected: 1, 2, 3 
var dc = new DataContainer('connection'); 
if (dc.fetch()) { 
    var data = dc.getData(); 
    for (var i = 0; i < data.length; i++) { 
    console.log(data[i]); 
    } 
} 

내가만큼 내가 생성자 함수에 새로운 DbConnection 객체를 생성 생성자 함수에 키워드 대신 VAR와 속성을 정의하고, 바인딩을 포함 할 수와 같은 코드를 고정 getData (다음 코드 참조)을 호출하는 동안 콜백 함수에 전달합니다. 유일한 문제는 동기 함수 내에서 비동기 함수 (getData)를 호출하는 방법입니다.

function DataContainer(connectionString) { 
    this.dataFetched = false; 
    this.dbConnection = new DbConnection(connectionString); 
} 

DataContainer.prototype.getData = function() { 
    if (!this.dataFetched) 
    throw "Data not fetched!"; 
    return this.data; 
} 

DataContainer.prototype.fetch = function() { 
    this.dbConnection.getAllData(function (err, result) { 
    if (err) { 
     delete this.data; 
     this.dataFetched = false; 
     return false; 
    } else { 
     this.data = result; 
     this.dataFetched = true; 
     return true; 
     } 
    }.bind(this)); 
} 

는 동기 기능입니다 가져오고 우리는 비동기 그것을 만들 수 없습니다. getData은 비동기 함수이며 동기화 할 수 없습니다. 이제 우리는 어떻게 사용할 수 getData 안에 가져 오기 ???

답변

1

fetch은 동기식이지만 getAllData은 비동기식입니다. 따라서 getAllData은 동기식 기능처럼 작동하게합니까? 당신이 얻을 수있는 하나의 (그리고 아마도 유일한) 방법은 async/await을 사용하는 것입니다 :

DataContainer.prototype.fetch = async function fetch() { 
    return await new Promise(resolve => { 
     this.dbConnection.getAllData((err, result) => { 
     if (err) { 
      delete this.data; 
      this.dataFetched = false; 
     } else { 
      this.data = result; 
      this.dataFetched = true; 
     } 
     resolve(this.dataFetched); 
     }); 
    }); 
} 

이 소비 코드 동기 작업으로 전화를 처리 할 수 ​​