我一直在使用ES6 Promise。

通常,Promise是这样构造和使用的

new Promise(function(resolve, reject){
    if (someCondition){
        resolve();
    } else {
        reject();
    } 
});

但我一直在做下面这样的事情,为了灵活起见,把决心放在外面。

var outsideResolve;
var outsideReject;
new Promise(function(resolve, reject) { 
    outsideResolve = resolve; 
    outsideReject = reject; 
});

后来

onClick = function(){
    outsideResolve();
}

这很好,但是否有更简单的方法来做到这一点?如果不是,这是一个好的实践吗?


当前回答

以防有人来找简化这个任务的util的typescript版本:

export const deferred = <T>() => {
  let resolve!: (value: T | PromiseLike<T>) => void;
  let reject!: (reason?: any) => void;
  const promise = new Promise<T>((res, rej) => {
    resolve = res;
    reject = rej;
  });

  return {
    resolve,
    reject,
    promise,
  };
};

这可以用在。如:

const {promise, resolve} = deferred<string>();

promise.then((value) => console.log(value)); // nothing

resolve('foo'); // console.log: foo

其他回答

感谢每个在这篇文章中发帖的人。我创建了一个模块,其中包括前面描述的Defer()对象以及在其上构建的其他一些对象。它们都利用Promise和简洁的Promise回调语法在程序中实现通信/事件处理。

延迟:可以远程解决失败的承诺(在承诺体之外) 延迟:在给定时间后自动解决的承诺 TimeOut:承诺在给定时间后自动失败。 循环:使用promise语法管理事件的可重新触发承诺 队列:基于承诺链的执行队列。

Rp = require("openpromise")

https://github.com/CABrouwers/openpromise https://www.npmjs.com/package/openpromise

我想分享一些不同的东西,这是这个话题的延伸。

有时,您希望“任务承诺”在解析时自动在相同的地址(属性或变量)重新创建。可以创建一个外部解析器来完成这个任务。

一个带有外部解析器的重复承诺的例子。无论何时调用解析器,都会在相同的地址/变量/属性处创建一个新的承诺。

let resolvePromise;
let thePromise;

const setPromise = (resolve) => {
  resolvePromise = () => {
    resolve();
    thePromise = new Promise(setPromise);   
  }
}
thePromise = new Promise(setPromise);

(async () => {
  let i = 0;
  while (true) {
    let msg = (i % 2 === 0) ? 'Tick' : 'Tock';
    document.body.innerHTML = msg;
    setTimeout(resolvePromise, 1000);
    await thePromise;
    i++;
  }
})();

https://jsfiddle.net/h3zvw5xr

我们的解决方案是使用闭包来存储解析/拒绝函数,并附加一个函数来扩展承诺本身。

模式如下:

function getPromise() {

    var _resolve, _reject;

    var promise = new Promise((resolve, reject) => {
        _reject = reject;
        _resolve = resolve;
    });

    promise.resolve_ex = (value) => {
       _resolve(value);
    };

    promise.reject_ex = (value) => {
       _reject(value);
    };

    return promise;
}

使用它:

var promise = getPromise();

promise.then(value => {
    console.info('The promise has been fulfilled: ' + value);
});

promise.resolve_ex('hello');  
// or the reject version 
//promise.reject_ex('goodbye');

如何创建一个函数劫持拒绝并返回它?

function createRejectablePromise(handler) {
  let _reject;

  const promise = new Promise((resolve, reject) => {
    _reject = reject;

    handler(resolve, reject);
  })

  promise.reject = _reject;
  return promise;
}

// Usage
const { reject } = createRejectablePromise((resolve) => {
  setTimeout(() => {
    console.log('resolved')
    resolve();
  }, 2000)

});

reject();

首先在浏览器或节点上启用——allow-native -syntax

const p = new Promise(function(resolve, reject){
    if (someCondition){
        resolve();
    } else {
        reject();
    } 
});

onClick = function () {
    %ResolvePromise(p, value)
}