稍后解决承诺 [英] Resolve promise at a later time
问题描述
我想构建一个Promise,但是将解决方案推迟到以后。下面的代码创建了一个Promise,但是可以立即解决。
I would like to construct a Promise, but defer resolution until later. The code below creates a promise, but it is resolved immediately. How can I control when the promise gets evaluated?
var p = new Promise((resolve, reject) => {
resolve(1);
})
.then((p1) => {
console.log(p1 + 1);
});
更新:为澄清起见,希望将promise的声明与其执行分开的原因是:根据某些参数动态添加然后
回调。
UPDATE: To clarify, the reason for wanting to separate the declaration of the promise from its execution is to add then
callbacks dynamically, based on some arguments.
推荐答案
您可以将 resolve
和 reject
传递给要使用的任何异步函数。这样的函数可以在完成工作时调用它。这是Node中可运行的示例。如果运行此命令,它将在当前目录中执行 ls -l </ code>。
execSomething
函数仅接受回调,而 promiseToExec
函数则通过了 resolve,拒绝
回调到 execSomething
而不是立即调用它们中的任何一个。
You can pass resolve
and reject
to whatever asynchronous function you want to use. And such function can call it whenever it is done doing its work. Here is an example runnable in Node. If you run this, it will execute ls -l
in your current directory. The execSomething
function just takes callbacks and the promiseToExec
function passed the resolve, reject
callbacks to execSomething
rather than call either of them immediately.
const childProcess = require("child_process");
function execSomething(command, options, onSuccess, onError) {
childProcess.exec(command, options, (err, stdout, stderr) => {
if (err) {
onError(err);
}
onSuccess(stdout, stderr);
});
}
function promiseToExec(command, options) {
return new Promise((resolve, reject) => {
execSomething(command, options, resolve, reject);
});
}
promiseToExec("ls -l").then(console.log.bind(console));
Kazlauskis 建议这样做:
var resolve;
var promise = new Promise(function(fulfill) {
resolve = fulfill;
});
不要这样做!。
当回调中发生异常时,您将传递给 new Promise
,promise的规范就是这样将自动转换为承诺拒绝。因此,如果在回调函数中发生抛出错误...
的情况,您将获得自动转换。
When an exception happens in the callback you pass to new Promise
, the specification for promises is such that the exception will automatically be converted into a promise rejection. So if anything does throw Error...
inside the callback you get automatic conversion.
如果保存解决
回调并将逻辑移到传递给 new Promise
的回调之外,那么您不会获得此自动转换。在回调之外引发的异常将仅沿堆栈传递,而不会转换为承诺拒绝。这很糟糕,因为它要求您函数的用户使用 .catch
来捕获被拒绝的承诺和 try ... catch
引发异常。这是一个不良的设计实践。
If you save the resolve
callback and move your logic outside of the callback you pass to new Promise
, then you do not get this automatic conversion. An exception thrown outside the callback will just be passed up the stack without being converted to a promise rejection. This is bad because it requires users of your function to use .catch
to catch rejected promises and try...catch
for thrown exceptions. This is a bad design practice.
以下代码说明了此问题:
Here's code illustrating the issue:
// This is how things should be done.
function makeGoodPromise(num) {
return new Promise((resolve) => {
if (num < 0) {
throw new Error("negative num");
}
resolve(num);
});
}
// This is a bad approach because it will sometimes result in synchronous
// exceptions.
function makeBadPromise(num) {
let resolve;
const p = new Promise((fullfil) => {
resolve = fullfil;
});
if (num < 0) {
throw new Error("negative num");
}
resolve(num);
return p;
}
// Shoring up the bad approach with a try... catch clause. This illustrates what
// you need to do convert the exception into a rejection. However, why deal with the
// additional scaffolding when you can just take the simpler approach of not
// leaking the callbacks??
function makeBadPromise2(num) {
let resolve, reject;
const p = new Promise((fullfil, deny) => {
resolve = fullfil;
reject = deny;
});
try {
if (num < 0) {
throw new Error("negative num");
}
resolve(num);
}
catch (e) {
reject(e);
}
return p;
}
makeGoodPromise(-1).catch(() => console.log("caught the good one!"));
try {
makeBadPromise(-1).catch(() => console.log("caught the bad one!"));
}
catch(e) {
console.log("Oops! Synchronous exception: ", e);
}
makeBadPromise2(-1).catch(() => console.log("caught the bad2 one!"));
在Node中执行它时,输出为:
When I execute it in Node, this is the output:
Oops! Synchronous exception: Error: negative num
at makeBadPromise (/tmp/t12/test2.js:17:11)
at Object.<anonymous> (/tmp/t12/test2.js:48:3)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.runMain (module.js:604:10)
at run (bootstrap_node.js:394:7)
at startup (bootstrap_node.js:149:9)
caught the good one!
caught the bad2 one!
这篇关于稍后解决承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!