Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/434.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 定义空的蓝知更鸟承诺,如Q_Javascript_Promise_Q_Bluebird - Fatal编程技术网

Javascript 定义空的蓝知更鸟承诺,如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

通过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 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