延迟对象在解析之前返回
deferred object returning before resolving
我正在将 when 库与 Node js 一起使用。我创建了一个延迟对象,将 resolve 放在封装的 Mongoose findOne() 函数中,并将 return promise 放在外面。但似乎我的承诺总是在检索数据之前 returned。
User.prototype.getProfile = function(criteria) {
var deferred = when.defer();
var options = {
criteria: criteria,
select: 'name id email'
};
this.User.load(options, function(err, data) {
if (data) {
this.name = data.name;
this.email = data.email;
this.id = data.id;
} else {
return false;
}
console.log(data);
deferred.resolve();
});
console.log('returning promise');
return deferred.promise;
};
来电者
User.getProfile(req.query).then(
function success(data) {
res.send('Hello ' + User.name);// Hello ''
}
);
在 data
之前输出 'returning promise'
这就是 promises
的工作方式。
由于您有一个异步任务需要一些时间,并且 JavaScript
是一种单线程语言,您不想阻塞您的代码并等待该异步操作自行完成 - 否则没有人会使用 JavaScript
!!
那你是做什么的?您创建一个 promise
并继续您的代码。
您向该 promise
添加回调,当承诺得到解决时,您的回调将被调用。
我没有使用when
库,但你想要做的是这样的:
User.prototype.getProfile = function(criteria){
var deferred = when.defer();
var options = {
criteria : criteria,
select : 'name id email'
};
this.User.load(options, function(err, data) {
if (data) {
this.name = data.name;
this.email = data.email;
this.id = data.id;
console.log(data);
// the callback will invoke after the deferred object is resolved.
deferred.promise.then(function(o){ console.log('resolved!!!'); });
deferred.resolve(data);
}else{
deferred.reject('something bad occured');
return false;
}
});
return deferred.promise;
};
是的,promise 将返回给调用者而不是数据,这就是我们可以利用异步函数的方式。这是处理异步调用的常见操作顺序,
进行异步调用。
Return 一个 Promise
给来电者。
此时,调用者不必等待结果。它可以简单地定义一个 then
函数,它知道当数据准备好时该做什么并继续执行下一个任务。
稍后的时间点,当您从异步调用中获得结果时解决(或拒绝,如果失败)承诺。
使用异步调用的结果在 Promise
对象上执行 then
函数。
所以,你的代码需要稍微修改一下,像这样
User.prototype.getProfile = function(criteria) {
var deferred = when.defer();
var options = {
criteria: criteria,
select: 'name id email'
};
this.User.load(options, function(err, data) {
if (err) {
// Reject, if there is an error
deferred.reject(err);
} else {
// Resolve it with actual data
deferred.resolve(data);
}
});
return deferred.promise;
};
然后你的来电者会做这样的事情
userObject.getProfile()
.then(function(profileObject) {
console.log(profileObject);
// Do something with the retrieved `profileObject`
})
.catch(function(err) {
console.err("Failed to get Profile", err);
});
// Do something else here, as you don't have to wait for the data
在这里,调用者只调用 getProfile
并附加一个函数,该函数说明如何处理返回的数据并继续。
Edit 如果你想更新同一个对象,那么你可以简单地使用类似的代码,但是你需要在其他变量中保留this
,因为this
的绑定发生在运行时。
User.prototype.getProfile = function(criteria) {
var deferred = when.defer();
var options = {
criteria: criteria,
select: 'name id email'
};
var self = this;
this.User.load(options, function(err, data) {
if (err) {
// Reject, if there is an error
deferred.reject(err);
} else {
self.name = data.name;
self.email = data.email;
self.id = data.id;
}
deferred.resolve(data);
});
return deferred.promise;
};
我正在将 when 库与 Node js 一起使用。我创建了一个延迟对象,将 resolve 放在封装的 Mongoose findOne() 函数中,并将 return promise 放在外面。但似乎我的承诺总是在检索数据之前 returned。
User.prototype.getProfile = function(criteria) {
var deferred = when.defer();
var options = {
criteria: criteria,
select: 'name id email'
};
this.User.load(options, function(err, data) {
if (data) {
this.name = data.name;
this.email = data.email;
this.id = data.id;
} else {
return false;
}
console.log(data);
deferred.resolve();
});
console.log('returning promise');
return deferred.promise;
};
来电者
User.getProfile(req.query).then(
function success(data) {
res.send('Hello ' + User.name);// Hello ''
}
);
在 data
'returning promise'
这就是 promises
的工作方式。
由于您有一个异步任务需要一些时间,并且 JavaScript
是一种单线程语言,您不想阻塞您的代码并等待该异步操作自行完成 - 否则没有人会使用 JavaScript
!!
那你是做什么的?您创建一个 promise
并继续您的代码。
您向该 promise
添加回调,当承诺得到解决时,您的回调将被调用。
我没有使用when
库,但你想要做的是这样的:
User.prototype.getProfile = function(criteria){
var deferred = when.defer();
var options = {
criteria : criteria,
select : 'name id email'
};
this.User.load(options, function(err, data) {
if (data) {
this.name = data.name;
this.email = data.email;
this.id = data.id;
console.log(data);
// the callback will invoke after the deferred object is resolved.
deferred.promise.then(function(o){ console.log('resolved!!!'); });
deferred.resolve(data);
}else{
deferred.reject('something bad occured');
return false;
}
});
return deferred.promise;
};
是的,promise 将返回给调用者而不是数据,这就是我们可以利用异步函数的方式。这是处理异步调用的常见操作顺序,
进行异步调用。
Return 一个
Promise
给来电者。此时,调用者不必等待结果。它可以简单地定义一个
then
函数,它知道当数据准备好时该做什么并继续执行下一个任务。稍后的时间点,当您从异步调用中获得结果时解决(或拒绝,如果失败)承诺。
使用异步调用的结果在
Promise
对象上执行then
函数。
所以,你的代码需要稍微修改一下,像这样
User.prototype.getProfile = function(criteria) {
var deferred = when.defer();
var options = {
criteria: criteria,
select: 'name id email'
};
this.User.load(options, function(err, data) {
if (err) {
// Reject, if there is an error
deferred.reject(err);
} else {
// Resolve it with actual data
deferred.resolve(data);
}
});
return deferred.promise;
};
然后你的来电者会做这样的事情
userObject.getProfile()
.then(function(profileObject) {
console.log(profileObject);
// Do something with the retrieved `profileObject`
})
.catch(function(err) {
console.err("Failed to get Profile", err);
});
// Do something else here, as you don't have to wait for the data
在这里,调用者只调用 getProfile
并附加一个函数,该函数说明如何处理返回的数据并继续。
Edit 如果你想更新同一个对象,那么你可以简单地使用类似的代码,但是你需要在其他变量中保留this
,因为this
的绑定发生在运行时。
User.prototype.getProfile = function(criteria) {
var deferred = when.defer();
var options = {
criteria: criteria,
select: 'name id email'
};
var self = this;
this.User.load(options, function(err, data) {
if (err) {
// Reject, if there is an error
deferred.reject(err);
} else {
self.name = data.name;
self.email = data.email;
self.id = data.id;
}
deferred.resolve(data);
});
return deferred.promise;
};