[REDIS] 노드 / 레디 스 및 콜백와 제어 흐름 문제?
REDIS노드 / 레디 스 및 콜백와 제어 흐름 문제?
나는 노드와 레디 스와 제어 흐름 문제에 대한 몇 가지 조언을 요청할 수 있습니다하세요? (파이썬 코더 노력 일명는 자바 스크립트를 사용하세요)
client.smembers 및 client.get (레디 스 조회) 필요가 단순히 문을 것보다 콜백 할 이유를 나는 이해하지 않는다 - 그것은 매우 복잡 생활을한다.
기본적으로 나는 세트를 조회하고 싶습니다, 나는 세트에 대한 결과가있을 때 다음, 나는 각 결과에 대한 GET을 수행해야합니다. 나는 모든 데이터를 가지고 때, 나는 다시 클라이언트로 방송 할 필요가있다.
현재 내가 더러워 보인다 전역 객체를 사용하여, 두 개의 콜백 내에서이 작업을 수행. 심지어 확인이 안전 경우 아니에요 (가 완료 한 client.get의 코드 대기 서로를 시작하기 전에?).
현재 코드는 다음과 같습니다 :
var all_users = [];
// Get all the users for this page.
client.smembers("page:" + current_page_id, function (err, user_ids ) {
// Now get the name of each of those users.
for (var i = 0; i < user_ids.length; i++) {
client.get('user:' + user_ids[i] + ':name', function(err, name) {
var myobj = {};
myobj[user_ids[i]] = name;
all_users.push(myobj);
// Broadcast when we have got to the end of the loop,
// so all users have been added to the list -
// is this the best way? It seems messy.
if (i === (user_ids.length - 1)) {
socket.broadcast('all_users', all_users);
}
});
}
});
그러나 이것은 매우 지저분한 것 같다. 그것은이 작업을 수행하는 가장 좋은 방법은 정말? 하려면 어떻게해야 모든 조회가 socket.broadcast를 호출하기 전에 수행 한 것을 할 수 있는가?
긁힌 자국은 어떤 조언에 미리 감사드립니다 머리.
해결법
-
==============================
1.즉 노드가 무엇인지입니다. (필자는 확신이 항목은 더 여기 충분한 시간보다 논의되었다 해요, 다른 질문을 통해 보면, 거기 확실히이다)
즉 노드가 무엇인지입니다. (필자는 확신이 항목은 더 여기 충분한 시간보다 논의되었다 해요, 다른 질문을 통해 보면, 거기 확실히이다)
즉 콜백 함수에 대한 ERR을 무엇이다. 이것은 좀 노드의 표준 - 콜백의 첫 번째 매개 변수는 오류 개체 (null의 모든 것을 잘 경우)입니다. 그러니 그냥 확인하기 위해이 같은 것을 사용 오류없이 발생
if (err) { ... // handle errors. return // or not, it depends. } ... // process results
당신은 그것에 익숙해 있습니다. 사실은 코드가 잘 포맷 및 프로젝트가 교묘하게 구성 될 때, 그것은 좋은 찾는거야.
다른 방법은 다음과 같습니다 :
-
==============================
2.당신이 완전히 물건 콜백 스타일을 쓰기 싫어하는 경우에, 당신은 streamlinejs을 시도 할 수 있습니다 :
당신이 완전히 물건 콜백 스타일을 쓰기 싫어하는 경우에, 당신은 streamlinejs을 시도 할 수 있습니다 :
var all_users = []; // Get all the users for this page. var user_ids = client.smembers("page:" + current_page_id, _); // Now get the name of each of those users. for (var i = 0; i < user_ids.length; i++) { var name = client.get('user:' + user_ids[i] + ':name', _); var myobj = {}; myobj[user_ids[i]] = name; all_users.push(myobj); } socket.broadcast('all_users', all_users);
참고이 변형의 단점은 하나의 사용자 이름이 한 번에 인출 될 것입니다. 또한, 당신은 여전히이 코드는 정말 무엇을 알고 있어야합니다.
-
==============================
3.비동기은 훌륭한 라이브러리입니다 당신은 살펴 보셔야합니다. 왜 ? 클린 코드 / 공정 / 추적이 용이 등등
비동기은 훌륭한 라이브러리입니다 당신은 살펴 보셔야합니다. 왜 ? 클린 코드 / 공정 / 추적이 용이 등등
또한, 모든 비동기 함수는 루프에 대한 후 처리되는 것을 명심하십시오. 당신이 exemple, 그것은 잘못 "내가"값이 발생할 수 있습니다. 사용 폐쇄 :
for (var i = 0; i < user_ids.length; i++) { (function(i) { client.get('user:' + user_ids[i] + ':name', function(err, name) { var myobj = {}; myobj[user_ids[i]] = name; all_users.push(myobj); // Broadcast when we have got to the end of the loop, // so all users have been added to the list - // is this the best way? It seems messy. if (i === (user_ids.length - 1)) { socket.broadcast('all_users', all_users); } }); })(i)}
그것의 마무리는 비동기 같은 재귀 패턴을 사용할 때 무엇을 알고 당신이해야 (내가 생각하는) 않습니다. 그것의 많은 간단한은 스스로를하고.
async.series({ getMembers: function(callback) { client.smembers("page:" + current_page_id, callback); } }, function(err, results) { var all_users = []; async.forEachSeries(results.getMembers, function(item, cb) { all_users.push(item); cb(); }, function(err) { socket.broadcast('all_users', all_users); }); });
이 코드는 유효하지 않을 수 있습니다,하지만 당신은 그것을 할 방법을 알아낼 수 있어야합니다.
단계 라이브러리가 좋은도 (만 30 ~ 코드의 라인 내 생각)
-
==============================
4.모두가 콜백 지옥 동의 그래서 오른쪽, 더 부에노는 없다. 이 글을 쓰는 현재, 콜백은 노드의 죽어가는 기능입니다. 불행하게도, 레디 스 라이브러리는 약속을 반환에 대한 네이티브 지원이 없습니다.
모두가 콜백 지옥 동의 그래서 오른쪽, 더 부에노는 없다. 이 글을 쓰는 현재, 콜백은 노드의 죽어가는 기능입니다. 불행하게도, 레디 스 라이브러리는 약속을 반환에 대한 네이티브 지원이 없습니다.
그러나 당신이 그렇게 등에서 필요로 할 수있는 모듈이있다 :
유용한 =은 ( "좋은")을 필요로 CONST;
이 노드 런타임에 포함되어 있으며 우리가 사용할 수있는 유틸리티 함수, "promisify"인 그들 중 하나의 무리가되는 표준 라이브러리입니다 : https://nodejs.org/api/util.html#util_util_promisify_original
우리가 지금 업데이트 된 대답이 질문을 업데이트 할 수 있도록이, -v 8.0.0의 출시와 함께 추가되면서 지금은 물론 당신이 7 년 전에이 질문을 할 때, util.promisify (원본)은 존재하지 않았다.
그래서 promisify 함수이며, 우리는 client.get처럼 그것을 함수를 전달할 수 있습니다 ()하고 불쾌한 콜백 동작을 새로운 기능을 반환하고 대신이 약속을 반환하기 위해 좋은 깔끔한 그것을 감싼다.
그래서 promisify 마지막 인수로 콜백을 허용하고 대신 약속을 반환 할 수있는 기능을 소요하고 당신이 7 년 전 원 우리는 오늘날 여유 있다는 정확한 동작 이잖아처럼 들린다.
const util = require("util"); client.get = util.promisify(client.get);
우리가 util.promisify하기 위해 갔지 () 함수에 대한 참조를 전달하는 그래서 ().
이것은 대신 약속을 반환 콜백을 구현하는 그래서 대신에 그것을 감싸고, 당신의 기능을합니다. util.promisify () 그래서 promisified 된 새로운 기능을 반환합니다.
당신이 새로운 기능을 가지고 client.get에 기존의 것을 대체 할 수 있도록 (). 요즘, 당신은 레디 스 조회를위한 콜백을 사용할 필요가 없습니다. 그래서 지금 당신은 비동기 / await를 구문 같은 사용할 수 있습니다 :
CONST cachedMembers AWAIT client.get = ( '사용자'+ user_ids [I]);
우리가 해결해야 할이 대기하고 어떤 그래서 그것은 cachedMembers에 할당됩니다으로 해결합니다.
이 코드는 더욱 더 ES6 배열 도우미 방법을 사용하는 대신 루프에 대한 업데이트 할 정리 될 수있다. 나는 그렇지 않으면 영업 이익은 무용지물이었다,이 대답은 현재 사용자에게 유용합니다 바랍니다.
from https://stackoverflow.com/questions/7971945/control-flow-issue-with-node-redis-and-callbacks by cc-by-sa and MIT license
'REDIS' 카테고리의 다른 글
[REDIS] 어떻게 BookSleeve / 레디 스에서 PubSub 작동합니까? (0) | 2020.01.20 |
---|---|
[REDIS] 페이스 북 앱에 대한 레디 스 &시나와 지리 공간 색인 (0) | 2020.01.20 |
[REDIS] 어떤 명령이나 LUA 스크립트를 사용하여 레디 스에 저장된 여러 설정을 읽는 방법 (0) | 2020.01.20 |
[REDIS] 레디 스 데이터 구조 공간 요구 사항 (0) | 2020.01.20 |
[REDIS] 데이터베이스로 Yii2 + 레디 스 (0) | 2020.01.20 |