Node.js 如何在我要求之前不履行诺言

Node.js 如何在我要求之前不履行诺言,node.js,es6-promise,Node.js,Es6 Promise,我以为我已经弄明白了关于承诺的一切,但这一次实际上把我从床上扔了下来。当创建一个新的承诺时,执行者接受两个参数,为什么在我接受该承诺的then()或catch()之前要运行这个方法 运行节点6.2.2 import assert = require('assert'); describe("When working with promises", () => { let ar = [1, 2, 3, 4, 5, 6]; beforeEach(() => {

我以为我已经弄明白了关于承诺的一切,但这一次实际上把我从床上扔了下来。当创建一个新的承诺时,执行者接受两个参数,为什么在我接受该承诺的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();
    })
});

第一个测试失败,第二个测试成功。

要实现相同的行为,必须在工厂中包装承诺。您可以使用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();
 })
因此,您可以稍后调用无状态工厂,而无需在映射期间创建承诺(立即运行)

它允许您为以后的批处理执行使用,或自定义链接。

[…]承诺实现会立即执行executor函数,并传递resolve和reject函数[…]

这就是实现承诺的方式。您还可以创建一个新的承诺,并在承诺成功或失败后附加链接的
then()
catch()
处理程序

const p = new Promise(someExecutor);
// do some other things
p.then(someHandler);
// do some other things
p.catch(someOtherHandler);
如果您还不希望执行器执行,那么不要将其传递给
Promise
构造函数。

如果您检查,您会发现提供给构造函数的函数立即运行。它应该启动异步计算并在那里安装两个回调(这样,
resolve
reject
就不会立即调用,而是在计算完成或失败时调用)

Promise
函数不是异步计算,它只是将该计算和跟踪它所需的两个回调打包到一个漂亮的包中(并在完成此设置后立即返回)

第二个示例为每个数字创建一个匿名函数,但不调用其中任何一个

为什么这个方法在我接受then()或catch()之前运行


承诺不关心您是否安装了任何处理程序/链。无论是否有人在观看,计算都将已启动(或未启动)。

如果您只想运行(即,在连接“then()”处理程序之前不想运行),则可以使用纯可选项()

注意,这不是承诺,因此它没有“catch”方法

但它可以用于任何期望承诺的函数:

  • `承诺。所有([runLater])
  • 作为随后处理的
    的结果返回。然后(函数(){return runLater;})
  • Promise.resolve(runLater)
    =>现在它是一个带有then/catch的承诺

其中任何一个都将调用runLater.then方法。

谢谢,我一直认为我可以多次运行Promise构造函数。我可以,但在执行器中完成的所有工作只运行一次
var runLater = { 
  then: function(resolve, reject) { 
    var p = new Promise (...); // Creating a promise is optional
    resolve(p);  // you can return a plain value
  }
}