在我请求之前如何不运行一个承诺

我以为我已经知道了关于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(以便resolvereject不会被调用,但是只要计算完成或失败)。

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方法。