2015-12-14 3 views
3

Я хотел бы знать, если я делаю что-нибудь ужасное с этим примером кода:Доступ к внешним переменным в Promise цепи

something.on('register', function(user) { 
    client.setAsync(config.id, user.id) // From a package (I can't set the return value) 
    .then(function(){ 
     return user; // is this OK? 
    }) 
    .then(handleNewUser) 
    .then(getSomeStuff) 
    .catch(function(err) { 
     console.error("Promise chain error: ", err); 
    }); 
}); 

Будут ли какие-либо вопросы сферы применения? (условия гонки, где пользователь не так, как я думаю?)

Могу ли я передать пользователю более элегантный способ?

+2

'client.setAsync (config.id, user.id) .return (user)' - bluebird. –

+0

Вы также можете сделать '.then (() => handleNewUser (user))' или '.then (handleNewUser.bind (null, user))' make 'null', любой контекст' handleNewUser' должен работать правильно. Тем не менее, поскольку вы используете Bluebird, комментарий Беньямина - лучший подход. – sdgluck

ответ

0

Немного странно;

Нет никакой пользы от того, чтобы библиотека обещаний вызывала функцию handleNewUser, поскольку вам нужно добавить дополнительную функцию then, чтобы вернуть user, чтобы заставить ее работать.

Я бы рекомендовал просто вызов функции себя в then функции:

something.on('register', function(user) { 

    client.setAsync(config.id, user.id) 
    .then(function(){ return handleNewUser(user); } 
    .then(getSomeStuff) 
    .catch(function(err) { 
     console.error("Promise chain error: ", err); 
    }); 

}); 

[Примечание: Я не проверял эту версию] Или, вы можете быть в состоянии использовать частично применяется функция чтобы сделать это еще чище:

something.on('register', function(user) { 

    client.setAsync(config.id, user.id) 
    .then(handleNewUser.bind(this, user); } 
    .then(getSomeStuff) 
    .catch(function(err) { 
     console.error("Promise chain error: ", err); 
    }); 

}); 
1

Если что-нибудь, ваш шаблон лучше гарантирует то же user, чем если client.setAsync() должен был вернуть user. Если пакет плохо написан или плохо документирован, вы можете полностью вернуть какой-либо другой объект.

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

Работа с тем, что у вас есть, единственное очевидное улучшение было бы сформировать вашу цепь с одним меньше .then() следующим образом:

something.on('register', function(user) { 
    client.setAsync(config.id, user.id) // From a package (I can't set the return value) 
    .then(function() { 
     return handleNewUser(user); 
    }) 
    .then(getSomeStuff) 
    .catch(function(err) { 
     console.error("Promise chain error: ", err); 
    }); 
}); 

Вы можете наслаждаться чтением через эту question and its answers. В частности, найдите ответ, озаглавленный «Закрытие (и) закрытия», и вы увидите, что доступ к предыдущим значениям в закрытии является вполне разумным и правильным.