繁体   English   中英

使用Javascript原生Promise,在附加ableable之后解析Promise

[英]Using Javascript native promises, resolve a promise after thenables attached

有没有一种方法可以使用javascript本机promise( docs )创建promise并附加thenable,而在构造函数时不知道它将如何解决?

var foo = new Promise(function(resolve, reject) {
    // I don't know how this will resolve yet as some other object will resolve it
});

foo.then(function(val) {
  console.log("first " + val);
});

foo.resolve("bar");

foo.then(function(val) {
  console.log("second " + val);
});

// result
// first bar
// second bar

如果承诺的结果取决于其他承诺,则应使用then创建一个承诺。

@Norguard以直接形式提出的建议没有多大意义(甚至被称为递延反模式 )。 下面的代码做的完全一样,不需要额外的承诺:

var deferredSomething = function () {
  return waitAWhile()
      .then(doStuff)
      .then(function (result) {
          if (result.isGood) {
            return result.data;
          } else {
            throw result.error;
          }
       });
  });
};

而且,即使出于任何原因,您都需要预先创建promise,然后使用构造函数模式,这样做会更清洁:

var deferredSomething = function () {
  return new Promise(function (resolve, reject) {
    waitAWhile()
      .then(doStuff)
      .then(function (result) {
          if (result.isGood) {
            resolve(result.data);
          } else {
            reject(result.error);
          }
       });
  });
};

只需将它们保存在闭包中即可。

var makePromise = function () {
    var resolvePromise = null,
        rejectPromise  = null,

        promise = new Promise(function (resolve, reject) {
            resolvePromise = resolve;
            rejectPromise  = reject;
        });

    return { promise : promise, resolve : resolvePromise, reject : rejectPromise };
};


var deferredSomething = function () {
    var deferredThing = makePromise();
    waitAWhile()
        .then(doStuff)
        .then(function (result) {
            if (result.isGood) {
                deferredThing.resolve(result.data);
            } else {
                deferredThing.reject(result.error);
            }
        });

    return deferredThing.promise;
};

实际上,这是“递延”概念和“承诺”概念之间的大部分差异。 最顶层,它具有您可以将.then|.success|.done|etc...交给消费者时可以提供给其他人的实际遥控器。

将这些功能带入上游流程后,您可以使用返回的“ thenable”愉快地延迟加载任何所需的东西,然后随意使链成功或失败(或使其挂起)。 ..

更新

我认为,这很可能将继续是选择的答案,并继续被否决,这是他所遇到的确切问题的解决方案(即:改版代码不是考虑到ES6的承诺),我认为我们将添加一个更详细的示例,说明为什么有选择地使用此反模式可能比没有效果更好的原因:

MongoClient.connect("mongodb://localhost:21017/mydb", (err, db) => {
    db.collection("mycollection", (err, collection) => {
        collection.find().toArray((err, results) => {
            doStuff(results);
        });
    });
});

如果要编写一个库,请在这里,希望可以写点:

let dbConnected = MongoClient.connect(dbURL);

dbConnected
    .then(db => db.collection(myCollection))
    .then(collection => collection.find(query))
    .then(stream => doStuff(stream));

...或者:

composeAsync(
    (stream) => doStuff(stream),
    (collection) => collection.find(query),
    (db) => dbCollection(myCollection)
)(dbConnected);

...为了便于在库中使用,将每个函数体包装在实例化的Prom中是否有意义// find = curry(query,collection)return new Promise(resolve,reject){/ *整个函数体,在这里//做很多与mongo.db.collection.find的分辨率无关的事情,但与它的调用* / collection.find(query).toArray(/ node-callback /(err,result)有关) {if(err){reject(err);} else {resolve(result);}}); };

...或者看一下只需要解决特定于节点的回调的模式,是否有某种形式的promise-resolver更有意义,从而省去了写/复制粘贴的次数应该完全干燥的纯冗余线路?

// find = curry(query, collection)
let resolver = new NodeResolver();
collection.find(query).toArray(promise.resolve);
return resolver.promise;

是的,这是一种反模式... ...但是,这种反模式需要较少的击键,恢复了promise链的自然流,修复了Node的仅用于回调的API的问题,降低了发生错误的可能性等等等

是的,已经有执行此操作的库...针对X库或Y特定的解决方案...或全局覆盖各种模块(可怕)方法的解决方案...或基本上迫使您传递正在拨打的电话的所有详细信息:

wrapNodeMethod(fs, "read", url, config).then(data => { /*...*/ });

但是,要消除所有这些痛苦,却没有一个简单的解决方案:

a)将整个函数体包装在promise中,以将异步回调提供给解析器b)在库中使用反模式,以便将其他函数体完全不需要了解的解析器传递给Node回调。

即使数据需要在解析器中进行转换,以新的承诺返回转换后的集合仍然更有意义。

let resolver = new NodeResolver();
somethingAsync(resolver.resolve);
return resolver.promise.then(transformData).then(logTransform);

...而不是包装整个身体(包括变换等),仅用于闭包范围参考,只是为了避免使用“反模式”,而这种“反模式”明显违背了非常著名的JS平台/范例。

现在,就个人而言,如果IO || Node方法返回promise和/或流,以及进行回调,并将其作为平台的核心部分,我会更开心……这将不会发生。 ..

...但是您可能无法告诉我,在仍然使用ES6 Promises的情况下,减少编写并保持Node模块为DRY是一种“反模式”,因此没有为我提供更为雄辩的解决方案。

如果确实可以为我提供可以在任何 NodeJS回调中使用的功能,那么它的确提供了一种更为雄辩的解决方案,从而使我不必包装每个包含异步回调的方法的每个主体。在新的构造函数中,或者使用笨拙的调度程序方法,或者劫持整个模块以覆盖其全局功能...

...我很乐意收回我的声明,即与容易产生金字塔的API接口时,这种特定模式仍然非常有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM