2015-02-17 118 views
0

我有一個關於承諾的問題。承諾循環(藍鳥) - 在異步包裝對象

我正在使用Bluebird Promise庫並使用它構建async

我想瀑布承諾與使用的功能。

說我使用的承諾,像這樣:

Promise.resolve() 
.then(function() { 
    console.log("called 1") 
    return 1; 
}).then(function() { 
    return new Promise (function (res, rej) { 
    setTimeout(function() { 
     console.log("called 2") 
     res(2); 
    }, 1500); 
    }); 
}).then(function() { 
    console.log("called 3") 
    return 3; 
}); 

但這實際上是在等待一個循環,並在順序返回1,2,3。

如何將它包裝成一個功能,這樣我可以做這樣的事情:

a();b();c();,或a().b().c();其中一個()把東西到一個鏈條,B()把東西到一個鏈條,和c ()將某些東西放在鏈上。

從那時起()返回一個新的承諾,它都可以走出去的順序,所以像 不起作用:

var promise = Promise.resolve(); 
function a() { 
    promise.then(function() { 
    // do sync/async 
    }); 
} 
function b() { 
    promise.then(function() { 
    //do sync/async 
    }); 
} 
function c ... 

謝謝你的時間:]

我我不確定這裏的目標是什麼。你是否想要事先知道序列中的任意數量的序列?或者,這是一個序列被發現的情況嗎?該流的NodeJS接口是用於處理數目不詳的事情順序(@tadman)

序列是發現好了很多,目標是要叫a().b().c()b().a().d()能力。客戶端上的異步庫。

更新如果我這樣做@zerkms說它不能按預期的那樣工作。我的壞,應該工作正常,但缺乏上下文/代碼沒有給我足夠的信息展開。還是謝謝你的回答,因爲它給了我更多的思考。

更新:見我的答案

+0

'function a(promise){return promise.then(...); }' – zerkms 2015-02-17 21:38:18

+1

如果你在'then'塊中返回一個promise,那麼這個promise就會在鏈繼續之前被執行。通常這可以讓你根據需要任意分支。請記住,您必須明確地返回這個新的承諾,否則它將無法正確鏈接。你的getNext方法在這裏保持分支,它不會鏈接。 – tadman 2015-02-17 21:53:46

+0

我想我已經明白了,每次我打電話時都可以更新承諾,就像我的更新一樣。似乎是合法的?它工作,順便說一句,謝謝 – Plyto 2015-02-17 22:00:14

回答

0

感謝@tadman我想出了這個迄今爲止,似乎我希望它的工作。 問題是我沒有更新承諾,然後再調用它,它是分支而不是順序調用它。 這就是我想要的 - 將同步/異步的對象變成異步以允許鏈接。 Petka(@Esailija)也展示了通過擴展藍鳥圖書館來構建上面的DSL(semvar版本碰撞& git推送)的一個很好的例子,但對我而言這足夠了。

var Sample = function() { 
    this.promise = Promise.resolve(); 
}; 

Sample.prototype.a = function() { 
    this.then(function() { 
    console.log("1"); 
    }); 
    return this; 
}; 

Sample.prototype.b = function() { 
    this.then(function() { 
    return new Promise(function (res, rej) { 
     setTimeout(function() { 
     console.log("2"); 
     res(); 
     }, 500); 
    }); 
    }); 
    return this; 
}; 

Sample.prototype.c = function() { 
    this.then(function() { 
    console.log("3"); 
    }) 
    return this; 
}; 

Sample.prototype.chainPromise = function (func) { 
    this.promise = this.promise.then(func); 
}; 

var s = new Sample(); 
s.a().b().c(); 

或甚至然後而不是chainPromise?

Sample.prototype.then = function (func) { 
    this.promise = this.promise.then(func); 
    return this.promise; 
}; 
+0

您的'chainPromise'方法應該可以工作,我想知道爲什麼您不會將它用於您的示例中的'a','b','c'方法? – Bergi 2015-02-18 00:23:31

+0

是啊,它的任一鏈的好處,或者哪一個是有點相同:] – Plyto 2015-02-18 02:18:06

1

你可以使用一個scoped prototype,只是添加這些方法有

Promise.prototype.a = function() { 
    return this.then(function() { 
    console.log("called 1") 
    return 1; 
    }); 
}; 

Promise.prototype.b = function() { 
    return this.delay(1500).then(function() { 
    console.log("called 2") 
    return 1; 
    }); 
}; 

Promise.prototype.c = function() { 
    return this.then(function() { 
    console.log("called 3") 
    return 3; 
    }); 
}; 

我使用它來創建例如DSL的整齊使用git:

https://gist.github.com/petkaantonov/6a73bd1a35d471ddc586

+0

非常接近版本碰撞:] – Plyto 2015-02-18 02:48:28