Подтвердить что ты не робот

Определите пустое обещание Bluebird, как в Q

С 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 () {
   // ...
});
4b9b3361

Ответ 1

var resolver = Promise.defer();
setTimeout(function() {
    resolver.resolve(something); // Resolve the value
}, 5000);
return resolver.promise;

Эта строка довольно часто используется в документации .

Имейте в виду, что для этого обычно используется анти-шаблон. Но если вы знаете, что вы делаете, Promise.defer() - это способ получить резольвер, похожий на Q.

Однако этот метод не рекомендуется использовать. Bluebird даже устарел.

Вместо этого вы должны использовать этот способ:

return new Promise(function(resolve, reject) {
    // Your code
});

См. соответствующие биты документации: Promise.defer() и новый Promise().


После обновления вашего вопроса, вот ваша проблема: вы повторно используете одно и то же обещание для решения нескольких значений. Обещание может быть разрешено только один раз. Это означает, что вы должны использовать Promise.defer() столько раз, сколько у вас есть promises.

Тем не менее, увидев больше вашего кода, кажется, что вы действительно используете анти-шаблоны. Одним из преимуществ использования promises является обработка ошибок. Для вашего случая вам просто нужен следующий код:

var gitControl = Promise.promisifyAll(Main.gitControl);
var promises = [];
promises.push(gitControl.gitAddAsync(fileObj.filename, updateIndex));
return promises;

Этого должно быть достаточно, чтобы обрабатывать ваш прецедент. Это намного понятнее, и это также имеет преимущество действительно корректно обрабатывать ошибки.

Ответ 2

Флориан предоставил хороший ответ. Во имя вашего первоначального вопроса есть несколько способов начать цепочку с 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
    });

Ответ 3

Я столкнулся с этим, поскольку у меня был метод, который извлекает ресурс в Интернете и возвращает содержимое, но я хочу, чтобы он обрабатывал таймауты соединений и повторял до 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;
    });