如何在我要求之前不 运行 Promise
How to not run a Promise before I ask to
我以为我对 Promise 已经完全了解了,但这个真的把我赶下了床。当使用带有两个参数的执行程序创建新的 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();
})
});
第一次测试失败,第二次测试成功。
要实现相同的行为,您必须在工厂中包装承诺。您可以为此使用 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();
})
所以你有无状态的工厂可以稍后调用而不会在映射期间创建承诺(运行 立即)。
它允许您compose and join Promises for later batch execution using Promise.all, Promise.race,或自定义链接。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise:
[...] The executor function is executed immediately by the Promise implementation, passing resolve and reject functions [...].
这就是 Promise 实现的方式。您还可以创建一个新的承诺,并在承诺已经成功或失败时附加链式 then()
或 catch()
处理程序。
const p = new Promise(someExecutor);
// do some other things
p.then(someHandler);
// do some other things
p.catch(someOtherHandler);
如果您还不想让执行器执行,那么请不要将它传递给 Promise
构造器。
如果查看documentation for Promise,你会发现给构造函数的函数是运行立即。它应该启动异步计算并在那里安装两个回调(这样 resolve
和 reject
不会立即被调用,而是在计算完成或失败时被调用)。
Promise
函数 不是 异步计算,它只是将该计算和您需要跟踪它的两个回调包装到一个漂亮的包中(并在完成此设置后立即 returns。
您的第二个示例为每个数字创建了一个匿名函数,但不调用它们中的任何一个。
why is this method running before I either take then() or catch() at that promise
Promise 不关心您是否安装任何 handlers/chains。无论是否有人在看,计算都会开始(或不开始)。
如果你只想要 运行 的东西(即不在之前)附加了一个 "then()" 处理程序,那么你可以使用普通的 then-ables ( 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 的函数:
- `Promise.all([运行稍后])
- return 作为当时处理的结果
.then(function() { return runLater; })
Promise.resolve(runLater)
=> 现在是 then/catch 的承诺
其中任何一个都会调用 runLater.then 方法。
我以为我对 Promise 已经完全了解了,但这个真的把我赶下了床。当使用带有两个参数的执行程序创建新的 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();
})
});
第一次测试失败,第二次测试成功。
要实现相同的行为,您必须在工厂中包装承诺。您可以为此使用 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();
})
所以你有无状态的工厂可以稍后调用而不会在映射期间创建承诺(运行 立即)。
它允许您compose and join Promises for later batch execution using Promise.all, Promise.race,或自定义链接。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise:
[...] The executor function is executed immediately by the Promise implementation, passing resolve and reject functions [...].
这就是 Promise 实现的方式。您还可以创建一个新的承诺,并在承诺已经成功或失败时附加链式 then()
或 catch()
处理程序。
const p = new Promise(someExecutor);
// do some other things
p.then(someHandler);
// do some other things
p.catch(someOtherHandler);
如果您还不想让执行器执行,那么请不要将它传递给 Promise
构造器。
如果查看documentation for Promise,你会发现给构造函数的函数是运行立即。它应该启动异步计算并在那里安装两个回调(这样 resolve
和 reject
不会立即被调用,而是在计算完成或失败时被调用)。
Promise
函数 不是 异步计算,它只是将该计算和您需要跟踪它的两个回调包装到一个漂亮的包中(并在完成此设置后立即 returns。
您的第二个示例为每个数字创建了一个匿名函数,但不调用它们中的任何一个。
why is this method running before I either take then() or catch() at that promise
Promise 不关心您是否安装任何 handlers/chains。无论是否有人在看,计算都会开始(或不开始)。
如果你只想要 运行 的东西(即不在之前)附加了一个 "then()" 处理程序,那么你可以使用普通的 then-ables ( 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 的函数:
- `Promise.all([运行稍后])
- return 作为当时处理的结果
.then(function() { return runLater; })
Promise.resolve(runLater)
=> 现在是 then/catch 的承诺
其中任何一个都会调用 runLater.then 方法。