2016-08-30 5 views
2

私はおそらくここのどこかでポイントを逃しているので、私はアドバイスを探しています。別の関数でノード内のコールバックの結果を使用する

クライアント接続をリッスンしているノード・サーバーがあり、受け取ったデータに基づいてAPIを呼び出します。

このAPIへの最初の呼び出しでは、それらをグループ化するために後続の呼び出しで使用する必要があるIDが取得されます。

私が苦労しているのは、APIへの呼び出しが必ず非同期であり、コールバックでIDを変数に割り当てることです。その非同期呼び出しがAPIサーバーによって処理されている間に、より多くのデータがクライアントから入ってきて、より多くのAPI呼び出しが必要になりますが、2番目の呼び出しが依存するため、最初の呼び出しの結果を知るまでは起動できません。

これを処理する適切な方法は何ですか? 2番目のAPI呼び出しの結果を約束するためにQを使用する必要があるように感じますが、どのように構造化するべきかはわかりません。または、最初に完了するまでAPIコールをキューに入れるだけですか?どうすればいい?

例の問題のコード:

var server = net.createServer(); 

//set up the callback handler 

server.on('connection', handleConnection); 

handleConnection(conn) { 
    //do some stuff... 
    firstAPICall(); 
    conn.on('data', handleData); 
} 

handleData(data) { 
    //do some stuff... 
    otherAPIcall(); 
} 

firstAPICall() { 
    client.get("http://myAPI/getID", function (data, response) { 
    conn.myID = data[0].myID; 
    } 
    } 
} 

otherAPICall() { 
    //How do I make sure I actually have a value 
    //in conn.myID from the first function??? 
    client.post("http://myAPI/storeData", { data: {myID:conn.myID, data:someData} }, function (data, response) { 
    //do some stuff... 
    } 
    } 
} 
+0

あなたが欠けている点は、「そのAPIへの最初の呼び出しでは、それらをグループ化するために後続の呼び出しで使用する必要があるIDが取得されます」ということです。それは必須条件かそうでないかのどちらかです。 – Tibrogargan

答えて

1

はい、これには約束が必要です。おそらくあなたは、余分な機能でclient.get呼び出しの結果のための約束を作成して考慮すべきである

handleConnection(conn) { 
    //do some stuff... 
    var idPromise = firstAPICall(); 
    conn.on('data', function handleData(data) { 
    //do some stuff... 
    otherAPIcall(idPromise).then(function(result) { 
     … 
    }); 
    }); 
} 

firstAPICall() { 
    return Q.Promise(function(resolve, reject) { 
    client.get("http://myAPI/getID", function (data, response) { 
     resolve(data[0].myID); 
    }); 
    }); 
} 

otherAPICall(idPromise) { 
    return idPromise.then(function(myID) { 
    return new Promise(function(resolve, reject) { 
     client.post("http://myAPI/storeData", { 
     data: {myID:myID, data:someData} 
     }, function (data, response) { 
     //do some stuff... 
     resolve(…); 
     }); 
    }); 
    }); 
} 

:非同期的に最初の呼び出しから解決されたidの約束を行い、その後、後続の呼び出しでそれを使用します。また、ここで正しくエラーを処理し、rejectを呼び出してください。 clientがノードコールバック規則を使用する場合、Qにはsome nice helper functionsが含まれます。

+0

私は最後に約束事に行きました。それはうまくいっているようです - ありがとう! – Kristan

1

は約束を使用してみてください。次に、「then」を使用して他のAPICall()を呼び出します。

1

接続直後にデータを送信すると思われると思います。したがって、IDを持っていれば他のAPICallを単純化してチェックインするだけで、そうでない場合はコールバックを使うことができます。プロミスやasync/awaitのキーワードを使用すると、ラインをより良くすることができますが、これは必須ではありません。

var server = net.createServer(); 

//set up the callback handler 

server.on('connection', handleConnection); 

handleConnection(conn) { 
    conn.on('data', handleData(connm, data)); 
} 

handleData(conn, data) { 
    //do some stuff... 
    otherAPIcall(conn); 
} 

checkID(conn, cb) { 
    if (!conn.myID) { 
    client.get("http://myAPI/getID", function (data, response) { 
     conn.myID = data[0].myID; 
     cb(); 
    }); 
    } else { 
    cb(); 
    } 
} 

otherAPICall(conn) { 
    checkID(conn, function() { 
    client.post("http://myAPI/storeData", { data: {myID:conn.myID, data:someData} }, function (data, response) { 
     //do some stuff... 
    }); 
    }); 
} 
0

約束は、((8/2 + 1この値は、すべての成功コールバックを介してチェーン値とコールバックが返される値で発生した後に常に解決され、

function async(value) { 
var deferred = $q.defer(); 
var asyncCalculation = value/2; 
deferred.resolve(asyncCalculation); 
return deferred.promise; 
} 

var promise = async(8) 
.then(function(x) { 
    return x+1; 
}) 
.then(function(x) { 
    return x*2; 
}) 
.then(function(x) { 
    return x-1; 
}); 
promise.then(function(x) { 
console.log(x); 
}); 

を通過することができるので、値9が記録されています)* 2 - 1)。

+1

はい、これは約束の仕組みですが、これは質問と何が関係していますか? – Bergi

+0

Btw、OPはAngular promisesではなくQを使用しています。 – Bergi

+0

ケースは、約束がどのように明確に機能し、どのように使用するかを示しています。私が約束をうまく理解すれば、どんなQかAngularjs $ qでも、それらは同じ原則に基づいています。あなたが約束の仕方を理解していれば、どのように別の領域でそれを使うことができないのでしょうか。 – Eric

関連する問題