[英]How to ensure the chain of promises return an object
I have this function that has a chain of promises and I want to return an object: 我有这个函数有一个promises链,我想返回一个对象:
var signIn = function(fb_ID,fb_accessToken) {
console.log("signin!")
var promise = new Parse.Promise();
var TokenStorage = Parse.Object.extend("tokenStorage");
var query = new Parse.Query(TokenStorage);
query.equalTo('facebookID', fb_ID);
query.ascending('createdAt');
var password;
var username;
var output = {};
var user;
// Check if this ID has previously logged in, using the master key
return query.first({ useMasterKey: true }).then(function(tokenData) {
// Update the accessToken if it is different.
if (fb_accessToken !== tokenData.get('fb_accessToken')) {
console.log('1')
user = tokenData.get('user');
user.fetch({
success: function(data) {
username = data.get('username')
tokenData.set('fb_accessToken', fb_accessToken);
/*
password = new Buffer(24);
_.times(24, function(i) {
password.set(i, _.random(0, 255));
password = password.toString('base64')
})
*/
password = (Date.now().toString(36) + Math.random().toString(36).substr(2, 10)).toUpperCase();
user.setPassword(password);
tokenData.set('password',password)
console.log('fetch')
return
}
}).then(function(){
tokenData.save(null, { useMasterKey: true }).then(function(tokenuser) {
console.log('tokensave')
user.save();
return Parse.User.logIn(username, password);
}).then(function(data) {
// Return the user object.
console.log('output return')
output.success = true
output.isnewuser = false
output.username = username;
output.password = password;
output.fb_accessToken = fb_accessToken;
//return Parse.Promise.as(output);
//promise.resolve(output)
//return promise
return output
});
})
} else {
console.log('2')
Parse.Promise.as().then(function() {
username = tokenData.get('username');
password = tokenData.get('password');
return
}).then(function(){
return Parse.User.logIn(username, password)
.then(function(data) {
// Return the user object
output.success = true
output.isnewuser = false
output.username = username;
output.password = password;
output.fb_accessToken = fb_accessToken;
console.log('oo'+JSON.stringify(output))
//return Parse.Promise.as(output);
//promise.resolve(output)
return output
});
})
}
})
//return promise
}
The function has two if statements and I would like that both will return 'output' object when I call: 该函数有两个if语句,我希望在调用时它们都返回'output'对象:
signIn(fb_ID,fb_accessToken).then(function(data){
if (data.success == true) {
console.log('inn'+JSON.stringify(data))
response.success(data)
}
else {
console.log('errr')
response.error(data)
}
})
The 'data' object should be the 'output' object inside the SignIn function. 'data'对象应该是SignIn函数内的'output'对象。 Any idea?
任何想法?
You should put return
before user.fetch
and tokenData.save
in first if
block. 你应该把
return
前user.fetch
和tokenData.save
在第一if
块。 In the else
block put return
before Parse.promise.as
. 在
else
块把return
之前Parse.promise.as
。
Your current implementation looks like something similar to this. 您当前的实现看起来像这样。
var someFunction = function () {
return mainPromise().then(function () {
if (someCondition) {
somePromiseOne().then(function () {
return data;
});
}
else {
somePromiseTwo().then(function () {
return data;
});
}
});
};
In the both cases you should put return
before somePromiseOne
and somePromiseTwo
in order to pass the data
to the promise chain. 在这两种情况下,您应该在
somePromiseOne
和somePromiseTwo
之前放置return
,以便将data
传递给promise链。
You can do quite a lot to tidy things up ... and get it working. 你可以做很多事情来整理东西......并让它发挥作用。
First, you can (and should) move the code from the user.fetch({ success:... })
callback into the following then's callback. 首先,您可以(并且应该)将代码从
user.fetch({ success:... })
回调移动到以下的回调中。 "Property-style" callbacks should be avoided when a promise interface is available (and already used). 当promise接口可用(并且已经使用)时,应该避免“Property-style”回调。
Then, you might aim for flow control as follows : 然后,您可以按如下方式进行流量控制:
doSomethingAsync().then(function() {
var promise;
if(condition) {
promise = ...; // deliver username and password
} else {
promise = ...; // deliver username and password
}
return promise.then(function(details) {
return login().then(function() {
// fully compose output object here
return details;
});
});
});
In practice, the code will be more extensive due to the number of async steps and the volume of synchronous code, particularly in the first condition. 实际上,由于异步步骤的数量和同步代码的数量,代码将更加广泛,特别是在第一种情况下。
In full, you might end up with something like this : 完全,你可能会得到这样的东西:
var signIn = function(fb_ID, fb_accessToken) {
var query = new Parse.Query(Parse.Object.extend('tokenStorage'));
query.equalTo('facebookID', fb_ID);
query.ascending('createdAt');
// Check if this ID has previously logged in, using the master key
return query.first({ useMasterKey: true }).then(function(tokenData) {
var promise;
// Update the accessToken if it is different.
if (fb_accessToken !== tokenData.get('fb_accessToken')) {
var user = tokenData.get('user');
promise = user.fetch().then(function(data) {
var details = {
username: data.get('username'),
password: (Date.now().toString(36) + Math.random().toString(36).substr(2, 10)).toUpperCase()
};
tokenData.set('fb_accessToken', fb_accessToken);
tokenData.set('password', details.password);
user.setPassword(details.password);
// Assuming here that `tokenData.save()` and `user.save()` are both async and can be executed in parallel.
return Parse.Promise.when([
tokenData.save(null, { useMasterKey: true }),
user.save()
]).then(function() {
return details;
});
});
} else {
// here `promise` mimics the final successful state of the promise in the other condition.
// ie. promise-wrapped details
promise = Parse.Promise.as({
username: tokenData.get('username'),
password: tokenData.get('password')
});
}
return promise.then(function(details) {
// whichever condition was executed, username and password details are delivered here in an identical format.
return Parse.User.logIn(details.username, details.password).then(function() {
details.success = true;
details.isnewuser = false;
details.fb_accessToken = fb_accessToken;
return details; // deliver details to signIn's caller
});
});
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.