Q.Promise의 사용에 있어서 역할이 혼란스러워 정리를 해두고자 한다.
수순
var promise = Q.Promise(function(resolve,reject,notify) {
???
});
상기 ???에 대해, resolve, reject, notify를 대입해 promise체인에 대한 동작을 확인한다.
1. return reject();
promise.catch(
function(ex) {
console.log("catch");
})
.fail(function(ex) {
console.log("fail");
})
.then(function(data) {
console.log(data);
});
결과 :catch
undefined
promise
.fail(function(ex) {
console.log("fail");
})
.then(function(data) {
console.log(data);
});
결과 :fail
undefined.
promise
.then(function(data) {
console.log(data);
})
.fail(function(ex) {
console.log("fail");
})
.catch(function(ex) {
console.log("catch");
});
결과 :fail
promise
.then(function(data) {
console.log(data);
})
.catch(function(ex) {
console.log("catch");
});
결과:catch
-> 에러를 분리해서 체이닝 할경우, 실패가 뒤로 가야하는것을 알 수 있다. 에러보다 뒤에있는 then은, 실행이 완료된 후 다음 동작을 의미한다. catch, fail을 then과 병용할때는 catch,fail이 then의 뒤에 붙을 필요가 있다. 그리고 이런 수순이 혼란스러울 정도라면 체이닝을 할게 아니라 then의 2,3번째 callback에서 호출해야 맞지 않을까?
promise
.then(function(data) {
console.log(data);
},function(err) {
console.log("err");
})
.catch(function(ex) { // or fail
console.log("catch");
});
결과err
-> catch/fail가 불려지지 않는다.
2. throw new Error("msg");
var promise = Q.Promise(function(resolve,reject,notify) {
throw new Error("test throw");
});
promise
.then(function(data) {
console.log(data);
res.json(data);
})
.fail(function(ex) {
console.log("fail");
})
.catch(function(ex) {
console.log("catch");
});
결과fail
promise
.then(function(data) {
console.log(data);
res.json(data);
})
.catch(function(ex) {
console.log("catch");
});
결과catch
-> throw역시 fail로 catch된다.
3. 그 외, notify
var promise = Q.Promise(function(resolve,reject,notify) {
console.log("call");
notify(1); // some progressive
notify(2); // some progressive
return resolve("Apple");
});
promise
.then(function(data) {
console.log(data);
},function(err) {
console.log("err");
},function(notification) {
console.log(notification);
})
.fail(function(ex) {
console.log("catch");
});
결과Apple
-> 1,2 notify가 호출되지 않았다...?
var promise = Q.Promise(function(resolve,reject,notify) {
Q.delay(1000)
.then(function() {
notify(1);
})
.delay(1000)
.then(function() {
notify(2);
})
.then(function() {
resolve("apple");
});
});
promise
.then(function(data) {
console.log(data);
res.json(data);
},function(err) {
console.log("err");
res.json(err);
},function(notification) {
console.log(notification);
});
결과1
2
apple
-> 각 결과가 1초 간격을 두고 불러졌다. 비동기에서만 notify가 반응하는듯 하다.
var promise = Q.Promise(function(resolve,reject,notify) {
Q.fcall(function() {
throw new Error("throw in another call stack"); });
return resolve("data");
});
promise
.then(function(data) {
console.log(data);
res.json(data);
})
.catch(function(ex) {
console.log("catch");
});
결과data
당연히 다른 callstack에서 throw 한 내용에 대해서는 catch 하지 않는다.
var promise = Q.Promise(function(resolve,reject,notify) {
Q.fcall(function() {
return reject(new Error("throw in another call stack"));
resolve("data");
});
});
promise
.then(function(data) {
console.log(data);
res.json(data);
})
.catch(function(ex) {
console.log("catch");
});
다른 call stack에서의 에러 호출은 상기와 같은 느낌으로 실시해야하고, 이후의 코드가 실행되지 않게 하기위해 (throw가 그렇듯) return하여 흐름을 끊어줄 필요가 있다.
var promise = Q.Promise(function(resolve,reject,notify) {
Q.fcall(function() {
return reject(new Error("throw in another call stack"));
resolve("data");
})
.then(function() {
console.log("is this code called?");
});
});
promise
.then(function(data) {
console.log(data); res.json(data);
})
.catch(function(ex) {
console.log("catch");
});
결과is this code called?
catch
-> 아... 위에서 reject를 리턴했다고 다음 then이 실행되지 않는건 아닌가보다.
var promise = Q.Promise(function(resolve,reject,notify) {
Q.fcall(function() {
return reject(new Error("throw in another call stack"));
resolve("data");
}).then(function(info) {
console.log("is this code called?");
console.log(info);
return "dummy";
}).then(function(info) {
console.log(info);
});
});
promise
.then(function(data) {
console.log(data);
res.json(data);
})
.catch(function(ex) {
console.log("catch");
});
결과is this code called?
undefined
dummy
catch
-> reject의 return값은 void인듯하다. 처음 info는 아무 정보도 가지고 있지 않다. 다음 info는 위에서 return한 값 "dummy"를 가지고 있다. 이들은 일종의 event chain으로 sync동작하게된다. 따라서 catch가 가장 마지막에 나오고 있다. 중간에 delay를 끼워 yield에 상당하는 동작을 하게되면 상황은 바뀌게 될것이다.
var promise = Q.Promise(function(resolve,reject,notify) {
Q.fcall(function() {
return reject(new Error("throw in another call stack"));
resolve("data");
}).then(function(info) {
console.log("is this code called?");
console.log(info);
return "dummy";
}).delay(1)
.then(function(info) {
console.log(info);
});
});
promise
.then(function(data) {
console.log(data);
res.json(data);
})
.catch(function(ex) {
console.log("catch");
});
결과is this code called?
undefined
catch
dummy
-> 예를 들자면 이런느낌이다.