为什么 Promise 构造函数需要一个 executor? [英] Why does the Promise constructor need an executor?

查看:57
本文介绍了为什么 Promise 构造函数需要一个 executor?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用 Promises 时,为什么可以resolvereject 的触发器不是在代码库的其他地方定义的吗?

When using Promises, why can't triggers for resolve and reject be defined elsewhere in the codebase?

我不明白为什么 resolvereject 逻辑应该被本地化到承诺声明的地方.这是疏忽,还是强制使用 executor 参数有好处?

I don't understand why resolve and reject logic should be localized where the promise is declared. Is this an oversight, or is there a benefit to mandating the executor parameter?

我认为 executor 函数应该是可选的,它的存在应该决定 promise 是否封装了解析.如果没有这样的要求,promise 会更加可扩展,因为您不必立即启动 async.承诺也应该是可重置的.这是一个 1 次切换,1 或 0,resolve()reject().可以附加多种并行和顺序结果:promise.then(parallel1)promise.then(parallel2) 以及 promise.then(seq1).then(seq2) 但参考特权玩家不能解决/拒绝转换

I believe the executor function should be optional, and that its existence should determine whether the promise encapsulates resolution or not. The promise would be much more extensible without such mandates, since you don't have to initiate async right away. The promise should also be resettable. It's a 1 shot switch, 1 or 0, resolve() or reject(). There are a multitude of parallel and sequential outcomes that can be attached: promise.then(parallel1) and promise.then(parallel2) and also promise.then(seq1).then(seq2) but reference-privileged players cannot resolve/reject INTO the switch

你可以在以后构建结果树,但你不能改变它们,也不能改变根(输入触发器)

老实说,顺序结果树也应该是可编辑的..假设您想在声明许多承诺链之后拼接一个步骤并做其他事情.重建承诺和每个顺序函数是没有意义的,特别是因为你甚至不能拒绝或破坏承诺......

Honestly, the tree of sequential outcomes should be edittable as well.. say you want to splice out one step and do something else instead, after you've declared many promise chains. It doesn't make sense to reconstruct the promise and every sequential function, especially since you can't even reject or destroy the promise either...

推荐答案

这叫做 由 Domenic 创造的揭示构造器模式.

基本上,这个想法是让您访问对象的部分,而该对象尚未完全构建.引用多梅尼克:

Basically, the idea is to give you access to parts of an object while that object is not fully constructed yet. Quoting Domenic:

我将其称为揭示构造函数模式,因为 Promise 构造函数正在揭示其内部功能,但仅限于构造所讨论的 Promise 的代码.解决或拒绝承诺的能力只向构造代码公开,关键是不会向任何使用承诺的人透露.所以如果我们把 p 交给另一个消费者,比如说

I call this the revealing constructor pattern because the Promise constructor is revealing its internal capabilities, but only to the code that constructs the promise in question. The ability to resolve or reject the promise is only revealed to the constructing code, and is crucially not revealed to anyone using the promise. So if we hand off p to another consumer, say

过去

最初,promise 与延迟对象一起使用,这在源自 JavaScript 承诺的 Twisted 承诺中是正确的.在旧的实现中,如 Angular 的 $q、Q、jQuery 仍然如此(但经常被弃用)和旧版本的蓝鸟.

The past

Initially, promises worked with deferred objects, this is true in the Twisted promises JavaScript promises originated in. This is still true (but often deprecated) in older implementations like Angular's $q, Q, jQuery and old versions of bluebird.

API 类似于:

var d = Deferred();
d.resolve(); 
d.reject();
d.promise; // the actual promise

它有效,但有问题.Deferreds 和promise 构造函数通常用于将非promise API 转换为promise.JavaScript 中有一个著名"问题,叫做 Zalgo - 基本上,这意味着 API 必须是同步的或异步的,但不能同时存在.

It worked, but it had a problem. Deferreds and the promise constructor are typically used for converting non-promise APIs to promises. There is a "famous" problem in JavaScript called Zalgo - basically, it means that an API must be synchronous or asynchronous but never both at once.

问题是 - 使用延迟可以做如下事情:

The thing is - with deferreds it's possible to do something like:

function request(param) {
   var d = Deferred();
   var options = JSON.parse(param);
   d.ajax(function(err, value) { 
      if(err) d.reject(err);
      else d.resolve(value);
   });
}

这里有一个隐藏的微妙错误 - 如果 param 不是有效的 JSON,这个函数会同步抛出,这意味着我必须将每个 promise 返回函数都包装在一个} catch (e) { 和一个 .catch(e => 来捕获所有错误.

There is a hidden subtle bug here - if param is not a valid JSON this function throws synchronously, meaning that I have to wrap every promise returning function in both a } catch (e) { and a .catch(e => to catch all errors.

promise 构造函数捕获此类异常并将它们转换为拒绝,这意味着您永远不必担心同步异常与带有 Promise 的异步异常.(它通过始终在下一个滴答"中执行 then 回调来保护你.

The promise constructor catches such exceptions and converts them to rejections which means you never have to worry about synchronous exceptions vs asynchronous ones with promises. (It guards you on the other side by always executing then callbacks "in the next tick").

此外,它还需要一个额外的类型,每个开发人员都必须了解 promise 构造函数没有的地方,这非常好.

In addition, it also required an extra type every developer has to learn about where the promise constructor does not which is pretty nice.

这篇关于为什么 Promise 构造函数需要一个 executor?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆