2017-05-22 25 views
-3

以下の質問はインタビューから取られます。私はいくつかの部分を解決することができましたが、私は立ち往生しました:バグ修正! (同期関数内で非同期関数を呼び出す方法)

次のコードのバグを修正しました。 DataContainerは、データベースからフェッチされたデータのキャッシュを提供するラッパーです。

を呼び出すは、データベースからデータをDbConnection 経由で取得する必要があります。フェッチが成功した場合は、を返します。;それ以外の場合はfalseを返します。 getDataを呼び出すと、キャッシュされたデータが返されるか、データがまだフェッチされていない場合は例外がスローされます。

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 inside 取り込み ???

答えて

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); 
     }); 
    }); 
} 

これは消費するコードは同期動作

としてコールを処理できるようになります
関連する問題