当前位置:  开发笔记 > 编程语言 > 正文

可选的Promise API

如何解决《可选的PromiseAPI》经验,为你挑选了1个好方法。

我有一个纯粹同步的验证库,但通常用作异步函数链的一部分.但是,我必须维护一个现有的同步API,并希望将promise API作为可选项.我可以以某种方式检测(在运行时)函数是否是Promise链的一部分?

回调这很容易,因为你可以检查是否传入了一个回调.我明白我可以传递一个可选的promise boolean,但这看起来不太优雅.

我还考虑过做一个回调接口,并使用库将回调接口转换为基于promise的接口.但是,我在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);
});

(旧)编辑澄清(但并非真的):

function preflight(thing){
  var validity = thing === 42;

  if(promise){
    if(validity){
      return Promise.resolve(validity);
    } else {
      return Promise.reject(validity);
    }
  } else {
    return validity;
  }
}

显然我可以在thenanon函数中进行相同的检查,但这并不比直接使用同步接口好多少.另请注意,这是一个非常简单的示例,在实际功能中会产生副作用thing并产生消息.

编辑只是为了更好地说明我的观点,这里有一些事情的主旨.



1> jfriend00..:

可以在promise链中使用同步函数.如果您有一个这样调用的同步API调用:

var info = myApi("foo");

这可以在承诺链中使用得很好:

someAsyncCall().then(myApi).then(someOtherFunction)

您不需要使myApi异步或返回以这种方式使用的承诺.在具有同步函数的promise链中,你唯一不能做的就是它不能是链中的第一个项,但它不需要.由于它是同步的,所以只要有人想要它首先执行,就可以在启动链之前调用它.或者,最坏的情况,您可以这样做:

Promise.resolve().then(myAPI).then(someOtherFunction);

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

不,你不能(除非你明确地传递了一些告诉它的信息),你不需要为了在诺言链中使用它.您不需要将promise作为.then()处理程序返回.您只需返回一个值,该值将成为链中该点的promise链的值.

我也明白你可以将承诺之间的常规函数​​夹在中间,但是在某些情况下,两者之间的行为会有所不同......例如返回false和抛出消息.

我不清楚为什么这种行为必须是不同的.如果返回false是正常的同步行为,那么你可以在promise链中做到这一点 - 链中的下一步只需要处理false传递给它的值,就像下一行同步代码那样.如果抛出异常是你的正常行为,你也可以在promise链中做到这一点(promise链会将异常变成拒绝),以下代码可以决定它想要处理的方式.如果您的同步函数根据它是否是promise链的一部分而表现不同,那么可以提出一个很好的论据.如果你看到两个不同行为的充分理由,那么你应该有两个不同的功能(可以用不同的方式记录)或传入的选项来确定行为.

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

您似乎认为通过承诺链调用时,您需要返回已解决或拒绝的承诺链.你不需要这样做.您只需返回一个正常值,promise链将继承您返回的值.除非你想让它成为promise链中的第一个函数,否则没有理由返回已解决或被拒绝的promise,但在这种情况下,它仍然不在promise链中,所以你永远无法检测到它.并且,没有理由将同步操作作为承诺链中的第一个操作.只需先调用同步操作,然后使用异步操作启动您的promise链.

这是一个在promise链中使用的同步函数的演示:

function log(str) {
    var div = document.createElement("div");
    div.innerHTML = str;
    document.body.appendChild(div);
}

// test async call
function delay(t, val) {
    return new Promise(function(resolve) {
        setTimeout(function() {
            resolve(val);
        }, t);
    });
}

function square(x) {
  return x * x;
}

log("Calculating the square of 9");
delay(500, 9).then(square).then(function(result) {
    log("Result = " + result);
});
推荐阅读
mobiledu2402851373
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有