簡體   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