Javascript 在链式承诺中,若第一个承诺要求不执行其余的承诺,那个么如何执行
我有4个方法,每个方法都返回一个承诺,我有它们的链式结构。但我在第一个承诺中有一个可以满足的条件,所以在这种情况下,我需要/不应该执行链中剩余的承诺。我该怎么做 以下是正在完成的4项任务 任务1)查看Mongo中是否存在数据,如果不存在 任务2)调用SOAP服务 任务3)使用SOAP的结果操作数据 任务4)将此文档放入Mongo 这很好,但当任务1有数据时,我不应该处理接下来的3个承诺(任务2、3、4) 这是我目前的代码Javascript 在链式承诺中,若第一个承诺要求不执行其余的承诺,那个么如何执行,javascript,promise,Javascript,Promise,我有4个方法,每个方法都返回一个承诺,我有它们的链式结构。但我在第一个承诺中有一个可以满足的条件,所以在这种情况下,我需要/不应该执行链中剩余的承诺。我该怎么做 以下是正在完成的4项任务 任务1)查看Mongo中是否存在数据,如果不存在 任务2)调用SOAP服务 任务3)使用SOAP的结果操作数据 任务4)将此文档放入Mongo 这很好,但当任务1有数据时,我不应该处理接下来的3个承诺(任务2、3、4) 这是我目前的代码 checkMongoForData(req, res) .then(fun
checkMongoForData(req, res)
.then(function (result) {
return makeTheSOAPcall(req, res, result)
.then(function (result) {
return fillTheReasonDescriptions(req, res, result);
})
.then(function (result) {
return upsertTheRespDocInMongo(req, res, result);
})
.then(function (result) {
res.status(200);
res.send({result: 'success', status: 200});
})
.catch(function (reject) {
res.status(reject.status);
res.send({result: reject.description, status: reject.status});
});
//我的函数定义如下
function checkMongoForData(req, res) {
return new Promise(function (resolve, reject) {
// TODO : the logic goes here
/// check to see for the data. If not there then continue
// if there is data, no need to do remaining tasks
});
}
我如何做到这一点?谢谢
我该怎么做
进行checkMongoForData
=>getDataFromMongo
,并在没有数据时将其拒绝。然后使用catch
捕获拒绝并触发获取数据的调用链:
getDataFromMongo(req, res)
.catch(function() {
// Didn't get the data, go get it
return makeTheSOAPcall(req, res, result)
.then(function (result) {
return fillTheReasonDescriptions(req, res, result);
})
.then(function (result) {
return upsertTheRespDocInMongo(req, res, result);
});
})
.then(function (result) {
// Got the data (one way or another)
res.status(200);
res.send({result: 'success', status: 200});
})
.catch(function (reject) {
// Something went irretrievably wrong
res.status(reject.status);
res.send({result: reject.description, status: reject.status});
});
如果UpsertTheRespocinMogo
的分辨率值不是数据本身,则可能需要添加。然后在其上添加,以更改输出的内容
下面是一个例子:
var fakeMongo=Object.create(null);
函数getDataFromMongo(键){
log(“getDataFromMongo:,key”);
返回新承诺(功能(解决、拒绝){
setTimeout(函数(){
if(Object.prototype.hasOwnProperty.call(fakeMongo,key)){
//我们有数据
解析({key:key,value:fakeMongo[key]});
}否则{
//我们没有数据
拒绝();
}
}, 100);
});
}
函数makeTheSOAPcall(键){
log(“makeTheSOAPcall:+key”);
返回新承诺(函数(解析){
决心({
钥匙:钥匙,
值:“+键的值”
});
});
}
函数填充原因说明(结果){
log(“填写原因说明:+result.key”);
返回承诺。解决(结果);
}
函数UpsertTheRespocinmongo(结果){
log(“upsertTheRespocinmongo:+result.key”);
返回新承诺(函数(解析){
fakeMongo[result.key]=result.value;
决心(结果);
});
}
//用法
retrieve(“key1”)//获取key1(不在那里)
.然后(函数(){
return retrieve(“key2”);//获取key2(不在那里)
})
.then(函数(){//Get key1再次出现(将出现)
返回检索(“键1”);
})
函数检索(键){
console.log(“检索:”+键);
返回getDataFromMongo(key/*req,res*/)
.catch(函数(){
//没有得到数据,去拿吧
返回makeTheSOAPcall(key/*req,res*/)
.然后(函数(结果){
返回填写原因说明(/*req,res,*/result);
})
.然后(函数(结果){
返回UPSERTTERESPOCINMONGO(/*req,res,*/result);
});
})
.然后(函数(结果){
//获取数据(以某种方式)
log(“获取数据:”,结果);
})
.catch(函数(拒绝){
//出了无法挽回的差错
log(“出错”,拒绝);
});
}
通常,有多种方法可以解决此问题
其中之一是:
- 在“四个任务链”之后使用附加的
catch()
- “拒绝”(但不是作为“错误”)案例中的
getDataFromMongo
方法
现有数据(带有我们可以实际检查的“伪”错误
(稍后)
- “duck typing”链本身的拒绝原因
这不是最好的,但它不会打破或显著改变你现有的承诺链(如果你愿意改变你的承诺链,你很可能会:
我喜欢ES6,因为我认为代码更可读
var reply = msg => {
res.status(msg.status);
res.send(msg);
};
var fetchAndUpdate = result =>
makeTheSOAPcall(req, res, result)
.then(result => fillTheReasonDescriptions(req, res, result))
.then(result => upsertTheRespDocInMongo(req, res, result));
checkMongoForData(req, res)
.then(result =>
//This is the key change. If result is not enpty, then return a promise
//resolve, else call fetchAndUpdate which returns a promise, which will.
//be resolved (or rejected) eventually.
result ? Promise.resolve() : fetchAndUpdate(result))
.then(() => reply({result: 'success', status: 200}))
.catch(e => reply({result: e.description, status: e.status}));
ES5
如果有数据,请调用reject()
。在这种情况下,如果您的条件得到满足(您收到了所需的数据),只需执行您的任务,不通过解析或拒绝来解决链接承诺。您能否提供有关您尝试执行的操作的更多信息?我想你的设计可能有一些缺陷。
var reply = msg => {
res.status(msg.status);
res.send(msg);
};
var fetchAndUpdate = result =>
makeTheSOAPcall(req, res, result)
.then(result => fillTheReasonDescriptions(req, res, result))
.then(result => upsertTheRespDocInMongo(req, res, result));
checkMongoForData(req, res)
.then(result =>
//This is the key change. If result is not enpty, then return a promise
//resolve, else call fetchAndUpdate which returns a promise, which will.
//be resolved (or rejected) eventually.
result ? Promise.resolve() : fetchAndUpdate(result))
.then(() => reply({result: 'success', status: 200}))
.catch(e => reply({result: e.description, status: e.status}));
var reply = function(msg) {
res.status(msg.status);
res.send(msg);
};
var fetchAndUpdate = function(result) {
return makeTheSOAPcall(req, res, result).then(function(result) {
return fillTheReasonDescriptions(req, res, result);
}).then(function(result) {
return upsertTheRespDocInMongo(req, res, result);
});
};
checkMongoForData(req, res).then(function(result) {
return result ? Promise.resolve() : fetchAndUpdate(result);
}).then(function() {
return reply({
result: "success",
status: 200
});
}).catch(function(e) {
return reply({
result: e.description,
status: e.status
});
});