Javascript 定义空的蓝知更鸟承诺,如Q
通过Q,我可以定义一个新的承诺:Javascript 定义空的蓝知更鸟承诺,如Q,javascript,promise,q,bluebird,Javascript,Promise,Q,Bluebird,通过Q,我可以定义一个新的承诺: var queue = q(); 但如果我有蓝鸟的话: var queue = new Promise(); 我得到: TypeError: the promise constructor requires a resolver function 我怎样才能得到与Q相同的结果 这是我的代码片段: var queue = q() promises = []; queue = queue.then(function () { return
var queue = q();
但如果我有蓝鸟的话:
var queue = new Promise();
我得到:
TypeError: the promise constructor requires a resolver function
我怎样才能得到与Q相同的结果
这是我的代码片段:
var queue = q()
promises = [];
queue = queue.then(function () {
return Main.gitControl.gitAdd(fileObj.filename, updateIndex);
});
// Here more promises are added to queue in the same way used above...
promises.push(queue);
return Promise.all(promises).then(function () {
// ...
});
这句话在英语中很常用
请注意,这通常是一种反模式。但是如果您知道自己在做什么,Promise.defer()
是一种获得解析器的方法,与Q的方法类似
但是,不鼓励使用这种方法。蓝鸟甚至反对它。
相反,您应该使用以下方法:
return new Promise(function(resolve, reject) {
// Your code
});
请参阅相关文档bits:和
更新您的问题之后,您的问题是:您正在重复使用相同的承诺来解决多个值承诺只能解决一次。这意味着您必须使用
promise.defer()
与承诺相同的次数
也就是说,在看到更多的代码之后,您似乎真的在使用反模式。使用承诺的一个优点是错误处理。对于您的情况,您只需要以下代码:
var gitControl = Promise.promisifyAll(Main.gitControl);
var promises = [];
promises.push(gitControl.gitAddAsync(fileObj.filename, updateIndex));
return promises;
这应该足以处理您的用例。它更清晰,而且它还具有真正正确处理错误的优势。Florian为您的原始问题提供了一个很好的答案,有几种方法可以启动蓝鸟链 其中一个最简单的方法是无需调用
Promise.resolve()
:
var queue = Promise.resolve(); //resolve a promise with nothing or cast a value
或
因此,您可以:
var queue = Promise.resolve()
promises = [];
queue = queue.then(function () {
return Main.gitControl.gitAdd(fileObj.filename, updateIndex);
});
// Here more promises are added to queue in the same way used above...
promises.push(queue);
return Promise.all(promises).then(function () {
// ...
});
不过,就我个人而言,我会这样做:
//arr is your array of fileObj and updateIndex
Promise.map(arr,function(f){ return Main.gitControl.gitAdd(f.filename,f.updateIndex).
then (function(result){
//results here
});
我遇到这个问题是因为我有一个方法,可以获取internet上的资源并返回内容,但我希望它能够处理连接超时,并在两次之间延迟重试X次 由于
Bluebird.defer
已被弃用,因此我使用了以下方法:
const Promise = require('bluebird');
var fetch = function (options, promise) {
var resolve, reject;
if (promise) {
resolve = promise.resolve;
reject = promise.reject;
promise = promise.promise;
} else {
promise = new Promise(function () {
resolve = arguments[0];
reject = arguments[1];
});
}
var retry = {promise: promise, resolve: resolve, reject: reject};
// Your logic here that you want to retry
if (typeof options.x === 'undefined') {
reject(new Error('X not defined'));
} else if (options.x < 3) {
options.x++;
options.retryAttempt = (options.retryAttempt || 0) + 1;
console.log(`Retrying in 1 second attempt ${options.retryAttempt}...`);
setTimeout(() => {
fetch(options, retry)
}, 1000);
} else {
resolve(options.x);
}
return promise;
}
fetch({x:0})
.then(res => {
console.log(res);
})
.catch(err => {
throw err;
});
const Promise=require('bluebird');
var fetch=函数(选项、承诺){
var解析、拒绝;
如果(承诺){
决心,决心;
拒绝,拒绝;拒绝;
允诺;允诺;
}否则{
承诺=新承诺(功能(){
解析=参数[0];
拒绝=参数[1];
});
}
var retry={promise:promise,resolve:resolve,reject:reject};
//您希望重试的逻辑
if(typeof options.x==‘未定义’){
拒绝(新错误('X未定义');
}否则如果(选项x<3){
options.x++;
options.retrytry=(options.retrytry | | 0)+1;
log(`Retrying in 1秒尝试${options.retrytry}…`);
设置超时(()=>{
获取(选项,重试)
}, 1000);
}否则{
解决(选项x);
}
回报承诺;
}
获取({x:0})
。然后(res=>{
控制台日志(res);
})
.catch(错误=>{
犯错误;
});
我发现这样的模式对于任何类型的集成测试都很有用
const responseResolver;
const response = new Promise(resolve => {
responseResolver = resolve;
}).then(data => {
console.log("data: ", data);
return data;
});
// mock some method that returns a promise (e.g. waits for a response)
service.getIceCreams = () => response;
// do some assertions while the response is pending
responseResolver("cookie dough"); // will trigger .then: "data: cookie dough"
// do some assertions now that the response is completed
谢谢,我会用一个“FIXME”来替换当前的方法。关于Q的方式。。。我应该使用
var resolver=Promise.defer(),queue=newpromise(解析器)代码>?它抛出了相同的错误。@FezVrasta查看示例以了解Promise.defer()
的用法。我已经更新了我的问题,添加了一段代码,我无法在那里实现您建议的方法,我得到了相同的错误。。。你能帮我吗?@FezVrasta在你的示例中,你只是在你的promises
数组中添加了一个promise。这仅仅是为了这个例子吗?@FlorianMargaine+1你能解释为什么新的允诺(函数(…
比使用Promise.defer()
更受欢迎吗?仅仅因为它“笨拙”和“容易出错”?如果你想让每个gitAdd等待下一个,你应该使用Promise.reduce
而不是Promise.map
。为什么Promise.resolve()
比Promise.cast()更好
?@FlorianMargaine good quesiton,Promsie.resolve在ES6规范中,当API创建时Promise.cast和Promise.resolve都在ES6规范和Bluebird中,我假设.cast
将在Bluebird 2.0中删除。这两个Bluebird.defer()
和Bluebird.cast()
在2.x版本中被弃用,为了启动一个“干净”的承诺链,最好使用Bluebird.resolve()
@pocesar这是正确的,我将删除.cast
,因为我们在2.0(甚至1.x iirc)中弃用它,我在哪里丢失了.defer
?请注意q
函数与Promise.cast
相同,而Promise
函数与q.Promise
相同。因此q()
的等价物是Promise.cast()
const Promise = require('bluebird');
var fetch = function (options, promise) {
var resolve, reject;
if (promise) {
resolve = promise.resolve;
reject = promise.reject;
promise = promise.promise;
} else {
promise = new Promise(function () {
resolve = arguments[0];
reject = arguments[1];
});
}
var retry = {promise: promise, resolve: resolve, reject: reject};
// Your logic here that you want to retry
if (typeof options.x === 'undefined') {
reject(new Error('X not defined'));
} else if (options.x < 3) {
options.x++;
options.retryAttempt = (options.retryAttempt || 0) + 1;
console.log(`Retrying in 1 second attempt ${options.retryAttempt}...`);
setTimeout(() => {
fetch(options, retry)
}, 1000);
} else {
resolve(options.x);
}
return promise;
}
fetch({x:0})
.then(res => {
console.log(res);
})
.catch(err => {
throw err;
});
const responseResolver;
const response = new Promise(resolve => {
responseResolver = resolve;
}).then(data => {
console.log("data: ", data);
return data;
});
// mock some method that returns a promise (e.g. waits for a response)
service.getIceCreams = () => response;
// do some assertions while the response is pending
responseResolver("cookie dough"); // will trigger .then: "data: cookie dough"
// do some assertions now that the response is completed