Created
April 29, 2016 07:48
-
-
Save RammusXu/69e8c2471b1cda4bb0cacbca823da3ef to your computer and use it in GitHub Desktop.
how to refactor it ?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var request = [ | |
profileUtil.createUser('[email protected]', 'qwer1234', 'test', 'Company'), | |
profileUtil.createUser('[email protected]', 'qwer1234', 'test2', 'Company'), | |
]; | |
request[0].then(function(value) { | |
return request[1]; | |
}) | |
.then(function(value) { | |
return request[2]; | |
}) | |
.then(function (value) { | |
done(); | |
}) | |
.catch(function(reason) { | |
console.log(reason); | |
// (reason.errmsg).should.include('duplica2te'); | |
done(); | |
}); |
createUser
// Initialize
var async = require('async'),
mongoose = require("mongoose");
// Test module
var Profile = require('./schema/profile.js');
var CompanyProfile = require('./schema/profile.js').CompanyProfile;
var TalentProfile = require('./schema/profile.js').TalentProfile;
// pinglib
var pinglib = require('pinglib');
var User = pinglib.User;
var main = {};
main.createUser = function(email, pwd, username, type) {
return new Promise(function(resolve, reject) {
console.log("name", username);
var newProfile;
if (type === 'Company') {
newProfile = new CompanyProfile();
newProfile.username = username;
} else if (type === 'Talent') {
newProfile = new TalentProfile();
newProfile.username = username;
} else {
reject("Can't recognize type = " + type);
}
var newUser = new User();
newUser.system_parameters = 1;
newUser.email = email;
newUser.pwd = pwd;
newUser.custom = { _profile: newProfile._id };
newProfile.save()
.then(function(doc) {
console.log("newProfile save", username);
return newUser.save();
})
.then(function(doc) {
console.log("resolve User", username);
return resolve(doc);
})
.catch(function(reason) {
console.log("reject ", username);
Profile.findByIdAndRemove(newProfile)
.then(function(doc) {
console.log("rollback Profile", username);
return reject(reason);
});
});
});
};
module.exports = main;
unit test
var requests = [
profileUtil.createUser('[email protected]', 'qwer1234', 'test', 'Company'),
profileUtil.createUser('[email protected]', 'qwer1234', 'test2', 'Company'),
];
requests[0].then(function(value) {
console.log("r0", value);
return requests[1];
})
.then(function(value) {
console.log("r1", value);
done();
})
.catch(function(reason) {
console.log("reject requests");
done();
});
console log
name test
name test2
newProfile save test
newProfile save test2
resolve User test
r0 { menu_crud: [],
_id: 57231f3e0acd2dfc3ae61372,
email: '[email protected]',
pwd: 'qwer1234',
custom: { _profile: 57231f3e0acd2dfc3ae61371 },
__v: 0 }
reject test2
rollback Profile test2
reject requests
name test
name test2
newProfile save test2
newProfile save test
resolve User test2
reject test
rollback Profile test
reject
when promise executing, i == request.length, so it will not work as expected
just let i is a copy(as a arg in a function), so that it will works
function ok(msg){
return new Promise(function(resolve, reject){
setTimeout(function(){
console.log(msg);
resolve(msg);
},1000);
});
}
function fail(msg){
return new Promise(function(resolve, reject){
setTimeout(function() {
console.log(msg);
reject(new Error('err'));
},1000);
});
}
function done(){
console.log('done');
}
var request = [ok('1'), ok('2'), fail('123'), ok('3')];
var promise = Promise.resolve('start');
for(var i=0; i<request.length; i++) {
function exec(i){
promise = promise.then(function(value){
console.log('value', value);
return request[i];
});
}
exec(i);
}
//all resolved
promise.then(function (value) {
console.log('value', value);
done();
})
.catch(function(error) {
console.log('err', error);
// (error.errmsg).should.include('duplica2te');
done();
});
這樣還是會執行
log
in 1
in 2
in 3
value start
1
2
123
3
value 1
value 2
function ok(msg){
return new Promise(function(resolve, reject){
console.log("in", msg);
setTimeout(function(){
console.log(msg);
resolve(msg);
},1000);
});
}
function fail(msg){
return new Promise(function(resolve, reject){
setTimeout(function() {
console.log(msg);
reject(new Error('err'));
},1000);
});
}
function done(){
console.log('done');
}
var request = [ok('1'), ok('2'), fail('123'), ok('3')];
var promise = Promise.resolve('start');
for(var i=0; i<request.length; i++) {
function exec(i){
promise = promise.then(function(value){
console.log('value', value);
return request[i];
});
}
exec(i);
}
//all resolved
// promise.then(function (value) {
// console.log('value', value);
// done();
// })
// .catch(function(error) {
// console.log('err', error);
// // (error.errmsg).should.include('duplica2te');
// done();
// });
其實他已經是對的了,只是他在request宣告時就開始執行了
ok('1') 這時候就已經執行了
所以這case可以改成下面這樣,就能一個接著一個做
function job(code){
return new Promise(function(resolve, reject){
setTimeout(function(){
console.log(code);
if(code >=0){
resolve(code);
}else{
reject(code);
}
},1000);
});
}
function done(){
console.log('done');
}
var request = [1, 2, -1, 3];
var promise = Promise.resolve('start');
for(var i=0; i<request.length; i++) {
function exec(i) {
promise = promise.then(function(value){
console.log('value', value, i);
return job(i);
});
}
exec(i);
}
//all resolved
promise.then(function (value) {
console.log('value', value);
done();
})
.catch(function(error) {
console.log('err', error);
// (error.errmsg).should.include('duplica2te');
done();
});
或是把job包成function 需要的時候再執行()
function ok(msg){
return function(){
return new Promise(function(resolve, reject){
setTimeout(function(){
console.log(msg);
resolve(msg);
},1000);
});
}
}
function fail(msg){
return function(){
return new Promise(function(resolve, reject){
setTimeout(function() {
console.log(msg);
reject(new Error('err'));
},1000);
});
}
}
function done(){
console.log('done');
}
var jobs = [ok('1'), ok('2'), fail('123'), ok('3')];
var promise = Promise.resolve('start');
for(var i=0; i<jobs.length; i++) {
function exec(i) {
promise = promise.then(function(value){
console.log('value', value, i);
//start exec here
return jobs[i]();
});
}
exec(i);
}
//all resolved
promise.then(function (value) {
console.log('value', value);
done();
})
.catch(function(error) {
console.log('err', error);
// (error.errmsg).should.include('duplica2te');
done();
});
By the way,
如果for loop那邊用的i是用let宣告的(不是var),應該就不會有這問題了
node要用es6語法的話,開頭加'use strict'
就可以用const, let宣告,可以避免很多var常見的陷阱(hoisting)
另外也支援這樣的匿名function
//1 原本宣告方法
let f1 = function(arg1,arg2) {
return arg1+arg2;
}
//2 單行,不用return跟分號
let f2 = (arg1, arg2)=> arg1+arg2
//3 多行,要自己加return
let f3 = (arg1, arg2)=> {
return arg1+arg2;
}
/*
其他還有一些list的operation
像是filter, map
*/
let arr = [1,2,3];
//[2,4,6]
console.log(arr.map(value=>value*2));
//[2,3]
console.log(arr.filter(value=>value>=2));
//[1,2,3]
console.log(arr);
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
console.log印出來是undefined