Javascript 可选承诺API

Javascript 可选承诺API,javascript,promise,Javascript,Promise,我有一个完全同步的验证库,但它通常作为异步函数链的一部分使用。但是,我必须维护一个现有的同步API,并且希望promise API是可选的 我是否可以(在运行时)以某种方式检测函数是否是承诺链的一部分? 这对于回调非常容易,因为您只需检查是否传入了回调。我知道我可以通过一个可选的承诺布尔值,但这似乎不雅观 我还考虑过使用回调接口,并使用库将回调接口动态转换为基于承诺的接口。然而,我在Haxe中工作,我更愿意将转换/抽象降到最低限度 我也知道你可以在承诺之间夹杂常规函数,但在某些情况下,两者的行为

我有一个完全同步的验证库,但它通常作为异步函数链的一部分使用。但是,我必须维护一个现有的同步API,并且希望promise API是可选的

我是否可以(在运行时)以某种方式检测函数是否是承诺链的一部分?

这对于回调非常容易,因为您只需检查是否传入了回调。我知道我可以通过一个可选的承诺布尔值,但这似乎不雅观

我还考虑过使用回调接口,并使用库将回调接口动态转换为基于承诺的接口。然而,我在Haxe中工作,我更愿意将转换/抽象降到最低限度

我也知道你可以在承诺之间夹杂常规函数,但在某些情况下,两者的行为会有所不同

最终编辑对于为什么我不能返回相同的值,有很多困惑,第一个示例(下面)似乎没有帮助。记住,这仍然是简化的

//mix of sync with promise 
new Promise(function(resolve, reject){
  var safeToAdd = thingTracker.preflight(newThing);
  if(safeToAdd){
    return client.request.addThing(newThing); //send request to server
  } else {
    reject(newThing.errorMessages); //requires explicit reject, cannot just pass results along
  }
}).then(function(newThing){ //client and server both cool with newThing?
  thingTracker.save(newThing);
}).catch(function(errorMessages){ //handles errorMessages from client and server
  ui.show(errorMessages);
});

//pure promise
thingTracker.preflight(newThing).then(function(){
  return client.request.addThing(newThing); //sends request to server
}).then(function(newThing){  //client and server both cool with newThing?
  thingTracker.save(newThing);
}).catch(function(errorMessages){ //handles errorMessages from client and server
  ui.show(errorMessages);
});
(旧)编辑以澄清(但实际上没有):

显然,我可以在
的anon函数中执行相同的检查,但这并不比直接使用sync接口好多少。还要注意,这是一个非常简单的示例,在实际函数中,
东西有副作用
,并且会产生消息


编辑为了更好地说明我的观点,下面是一个例子。

同步函数可以在承诺链中很好地使用。如果您有如下调用的同步API调用:

var info = myApi("foo");
在承诺链中可以很好地使用:

someAsyncCall().then(myApi).then(someOtherFunction)
您不需要使myApi异步,也不需要返回这样使用的承诺。在带有同步函数的承诺链中,唯一不能做的事情是,它不能是链中的第一项,但也不需要是。由于它是同步的,如果有人希望它首先执行,可以在启动链之前调用它。或者,在最坏的情况下,您可以:

Promise.resolve().then(myAPI).then(someOtherFunction);
我是否可以(在运行时)检测函数是否是 承诺链

不,您不能(除非您显式地向它传递一些告诉它的信息),并且您不需要在承诺链中使用它。您不需要返回成为
.then()
处理程序的承诺。您可以只返回一个值,该值将成为承诺链中该点的值

我也知道你可以在这两者之间夹杂常规函数 承诺,但在某些情况下,行为会有所不同 在两者之间。。。例如返回false与抛出消息

我不清楚为什么行为会有所不同。如果返回
false
是您正常的同步行为,那么您可以在承诺链中很好地执行此操作-链中的下一步只需要处理传递给它的
false
值,就像同步代码的下一行一样。如果抛出异常是您的正常行为,那么您也可以在承诺链中做得很好(承诺链会将异常变成拒绝),下面的代码可以决定如何处理该异常。有人可以提出一个很好的论点,即如果同步函数根据它是否是承诺链的一部分而表现不同,则情况会更糟。如果您看到了两种不同行为的原因,那么您可能应该拥有两个不同的函数(可以以不同的方式记录),或者传入一个确定行为的选项

根据您在编辑中添加的代码进行评论

您似乎认为,当通过承诺链调用时,您需要返回已解决或已拒绝的承诺链。你不需要那样做。您可以只返回一个正常值,承诺链将继承您返回的值。除非您希望它是承诺链中的第一个函数,否则没有理由返回已解决或已拒绝的承诺,但在这种情况下,它还不在承诺链中,因此您永远无法检测到它。而且,同步操作没有理由成为承诺链中的第一个操作。只需先调用同步操作,然后用异步操作启动承诺链

下面是在承诺链中使用的同步函数的演示:

someAsyncCall().then(myApi).then(someOtherFunction)
函数日志(str){
var div=document.createElement(“div”);
div.innerHTML=str;
文件.正文.附件(div);
}
//测试异步调用
功能延迟(t,val){
返回新承诺(函数(解析){
setTimeout(函数(){
解决(val);
},t);
});
}
函数平方(x){
返回x*x;
}
对数(“计算9的平方”);
延迟(500,9)。然后(平方)。然后(函数(结果){
日志(“结果=”+结果);

});同步函数可以在承诺链中很好地使用。如果您有如下调用的同步API调用:

var info = myApi("foo");
在承诺链中可以很好地使用:

someAsyncCall().then(myApi).then(someOtherFunction)
您不需要使myApi异步,也不需要返回这样使用的承诺。在带有同步函数的承诺链中,唯一不能做的事情是,它不能是链中的第一项,但也不需要是。由于它是同步的,如果有人希望它首先执行,可以在启动链之前调用它。或者,在最坏的情况下,您可以:

Promise.resolve().then(myAPI).then(someOtherFunction);
我是否可以(在运行时)检测函数是否是 承诺链

不,您不能(除非您显式地向它传递一些告诉它的信息),并且您不需要在承诺链中使用它。您不需要返回成为
.then()
处理程序的承诺。您可以只返回一个值,该值将成为
Function.prototype.it = (function() {
  return function() {
    var args = arguments;
    return function(){
        Array.prototype.push.apply(arguments, args);
        return this.apply(null, arguments);
    }.bind(this);
  };
}());

function foo(a, b, c) {
  console.log('a is ' + a, ' | b is ' + b, ' | c is ' + c);
};

// LOGIC :    
foo(1, 2, 3);
// SAME AS
foo.it(2, 3)(1);
// OR
foo.it(3)(1, 2);
// OR pretty useful for .then()
Promise.resolve(1).then(foo.it(2, 3));