使用Q我可以用以下内容定义新的承诺:
var queue = q();
但是如果我这样做,那就是Bluebird:
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 () {
// ...
});
答案 0 :(得分:37)
Florian提供了一个很好的答案为了您的原始问题,有几种方法可以与Bluebird建立链接。
最简单的一个就是在任何事情上调用Promise.resolve()
:
var queue = Promise.resolve(); //resolve a promise with nothing or cast a value
或
Promise.try(function(...){
return ...//chain here
});
所以你可以这样做:
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
});
答案 1 :(得分:23)
var resolver = Promise.defer();
setTimeout(function() {
resolver.resolve(something); // Resolve the value
}, 5000);
return resolver.promise;
此行常用于documentation。
请注意,这通常是使用它的反模式。但是,如果您知道自己在做什么,Promise.defer()
是一种获得类似问题的解析器的方法。
但是,不鼓励使用此方法。 Bluebird甚至已弃用它。
相反,你应该这样使用:
return new Promise(function(resolve, reject) {
// Your code
});
请参阅相关文档位:Promise.defer()和new Promise()。
更新问题后,问题出在此处:您重复使用相同的承诺来解决多个值。 承诺只能解决一次。这意味着您必须尽可能多地使用Promise.defer()
。
也就是说,在看到更多代码后,您似乎真的在使用反模式。使用promises的一个优点是错误处理。对于您的情况,您只需要以下代码:
var gitControl = Promise.promisifyAll(Main.gitControl);
var promises = [];
promises.push(gitControl.gitAddAsync(fileObj.filename, updateIndex));
return promises;
这应该足以处理您的用例。它更清晰,并且还具有真正正确处理错误的优势。
答案 2 :(得分:0)
我遇到过这种情况,因为我有一种方法可以在互联网上获取资源并返回内容,但是我希望它能够处理连接超时并重试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;
});
答案 3 :(得分:0)
我发现这样的模式对任何类型的集成测试都很有用。
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