2017-02-17 9 views
0

Я использую socket.io, и я хотел бы преобразовать функцию обратного вызова в простую функцию, основанную на обещании, где я могу вернуть значение.Как преобразовать этот аргумент обратного вызова в обещание?

Я пытаюсь преобразовать подтверждение здесь: socket.io/docs/#sending-and-getting-data-(acknowledgements)

socket.on('getGames', (data, callback) => { 
    Game.find(data) 
     .then(data => callback(data)); //explicit call to callback 
}); 

Я хотел бы вызвать функцию вместо того, чтобы такие как:

socketEvent(socket, 'getGames') 
    .then((data) => { 
     return Game.find(data); //returns a promise and can be chained 
    }); 

Я думаю, что-то вроде:

//this doesn't work 
const socketEvent = (socket, name) => { 
    return new Promise(function (resolve, reject) { 
     socket.on(name, (data, callback) => { 
      resolve((data) => callback(data)); 
     }); 
    }); 
}; 
+2

Возможно, вы вообще не должны. Сокет может запускать событие несколько раз, обещание - неправильный инструмент для его представления. – Bergi

+0

Ну, в любом случае, он будет срабатывать обратный вызов несколько раз. Контекст не так важен - мне все равно хотелось бы узнать, как преобразовать явный обратный вызов, как указано выше, в обещание. – Nazzanuk

+1

Обещание * не может * срабатывать несколько раз, вам там не повезло. В общем случае см. [Как преобразовать существующий API обратного вызова в обещания?] (Http://stackoverflow.com/q/22519784/1048572) – Bergi

ответ

1

Ваш второй фрагмент кода не аналогичен первому. В первом случае существует механизм отправки подтверждения, когда Game.find() получил свое значение, но во втором он не сможет отправить подтверждение после его завершения.

Я думаю, что это может быть близко к тому, что вы пытаетесь сделать:

const socketEvent = (socket, name) => { 
    return new Promise(function (resolve, reject) { 
     socket.on(name, (data, sendBack) => resolve({ data, sendBack })); 
    }); 
}; 

Вы могли бы потреблять его так:

socketEvent(socket, 'getGames') 
    .then({ data, sendBack } => Game.find(data).then(sendBack)) 
    .then(... more stuff); 

Однако, как уже отмечалось, есть все еще большая разница между этим и исходным кодом, потому что обещая версия будет только захватывать событие один раз (так работают обещания). Если вам нужно настроить механизм для захвата одного и того же события несколько раз, тогда обещания не являются подходящим инструментом для работы, и вам либо нужно использовать обратные вызовы, либо что-то вроде наблюдаемых.

1

Просто resolve(data). Нет необходимости в внутренней функции. Это вступит в цепочку обещаний.

Также не забудьте позвонить по телефону reject, если возникнут проблемы.

+0

Это не работает, поскольку я не вызывал 'callback' для возврата' data'. Мне нужно вызвать 'callback', когда обещание будет разрешено. – Nazzanuk

+0

@ Nazzanuk вы можете ссылаться на документацию? –

+0

@Nazzanuk Какие данные вы пытаетесь отправить назад? Откуда это взялось? – JLRishe