Основная проблема здесь server
. Это, по-видимому, общий ресурс, но он имеет только один обратный вызов, который вызывается с ответами. Этот дизайн не будет работать.
Вместо этого сервер должен принять обратный вызов для определенного вызова с запросом. Тогда делать то, что вы ищете, тривиально:
function requestPhoneCost () {
var product = "iPhone 7";
server.requestPrice(product, cost => showResult(product, cost));
}
В современном мире я бы использовал обещания, а не обратный вызов с ручным кодированием:
function requestPhoneCost () {
var product = "iPhone 7";
server.requestPrice(product)
.then(cost => showResult(product, cost))
.catch(error => { /* handle/report error */);
}
В обоих случаях это требует изменения server
, поэтому он отслеживает, какие обратные вызовы относятся к каким запросам. Это звучит намного сложнее, чем на самом деле (это на самом деле очень просто), но мы не можем помочь вам с кодом, который мы не видим (например, код server
).
Вы сказали, что в конструкторе соединения через веб-сокет настроен центральный onResponse
. IIRC, каждое сообщение в веб-сокете имеет уникальный идентификатор (и, если нет, предположительно, вы можете добавить его). После этого вы можете сохранить информацию об обещании, которое вы вернули для запроса, в Map
с указанием этого ID:
this.id = 0; // If you need to assign your own IDs
this.settlersById = new Map();
Вот концептуальный requestPrice
метод в вашем классе сервера:
requestPrice(product) {
const id = ++this.id;
const promise = new Promise((resolve, reject) => {
sendRequest({id, product});
this.settlersById.set(id, {resolve, reject});
});
}
затем в ответе
onResponse(response) {
const {id} = response;
const settlers = this.settlersById.get(id;
if (settlers) {
this.settlersById.delete(id);
if (/* response is a success */) {
resolve(response.data);
} else {
reject(/*...appropriate error...*/);
}
}
}
Опять же, это все концептуально, так как у нас нет класса вашего сервера. И он использует свой собственный идентификатор, в то время как websockets может предоставить один для вас.