Javascript 在链式承诺中,若第一个承诺要求不执行其余的承诺,那个么如何执行

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

我有4个方法,每个方法都返回一个承诺,我有它们的链式结构。但我在第一个承诺中有一个可以满足的条件,所以在这种情况下,我需要/不应该执行链中剩余的承诺。我该怎么做

以下是正在完成的4项任务

任务1)查看Mongo中是否存在数据,如果不存在

任务2)调用SOAP服务

任务3)使用SOAP的结果操作数据

任务4)将此文档放入Mongo

这很好,但当任务1有数据时,我不应该处理接下来的3个承诺(任务2、3、4)

这是我目前的代码

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
  });
});