在我请求之前如何不运行一个承诺
我以为我已经知道了关于Promise的一切,但是这个实际上让我起床了。 当用一个执行器创build一个新的Promise时需要两个参数,为什么这个方法在我接受then()或catch()之前就运行了
运行节点6.2.2。
import assert = require('assert'); describe("When working with promises", () => { let ar = [1, 2, 3, 4, 5, 6]; beforeEach(() => { }) it("should be perfectly fine but isn't when mapping to promises", (done) => { ar.map(num => { return new Promise((resolve, reject) => { done(new Error('Why on earth is ' + num + ' called')); }) }) done(); }) it("should be perfectly fine when mapping to methods", (done) => { ar.map(num => { return (resolve, reject) => { done(new Error(num + ' is not called ever')); } }) done(); }) });
第一次testing失败,第二次testing成功。
如果你检查Promise的文档 ,你会发现给构造函数的函数是立即运行的。 它应该启动asynchronous计算,并在那里安装两个callback(以便resolve
和reject
不会被调用,但是只要计算完成或失败)。
Promise
函数不是asynchronous计算,它只是将计算和两个callback包装起来,以便将它们一起追踪到一个很好的包中(并在完成此设置后立即返回)。
你的第二个例子为每个数字创build一个匿名函数,但是不会调用它们中的任何一个。
为什么这个方法在我接受then()或catch()的前提下运行
如果你安装任何处理程序/链,Promise不关心。 无论是否有人观看,计算都将开始(或不开始)。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise :
[…]执行器function由Promise实现立即执行,传递parsing和拒绝function[…]。
Promise实现就是这样的。 您也可以创build一个新的承诺,并在承诺已经成功或失败时,在以后连接then()
或catch()
处理程序。
const p = new Promise(someExecutor); // do some other things p.then(someHandler); // do some other things p.catch(someOtherHandler);
如果你不想执行者执行,那么不要把它传给Promise
构造者。
要达到同样的行为,你必须在工厂包装承诺。 你可以使用lambda函数。
it("should be perfectly fine but isn't when mapping to promises", (done) => { ar.map(num => { return () => new Promise((resolve, reject) => { done(new Error('Why on earth is ' + num + ' called')); }) }) done(); })
所以你有无国籍的工厂,以后再打电话,而不是在地图上创build承诺( 立即运行)。
它允许你使用Promise.all , Promise.race或自定义链接编写 和join Promise ,以便以后执行批处理。
如果你只想运行某个东西(即不是之前),则附加一个“then()”处理函数,那么你可以使用普通函数( https://promisesaplus.com/ )
var runLater = { then: function(resolve, reject) { var p = new Promise (...); // Creating a promise is optional resolve(p); // you can return a plain value } }
注意这不是一个Promise,所以它没有“catch”方法。
但它可以给任何期望承诺的函数:
- `Promise.all([runLater])
- 返回结果从一个然后处理
.then(function() { return runLater; })
-
Promise.resolve(runLater)
=>现在这是一个承诺,然后/ catch
其中的任何一个都会调用runLater.then方法。