稍后解决承诺 [英] Resolve promise at a later time

查看:70
本文介绍了稍后解决承诺的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想构建一个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆