web-dev-qa-db-ja.com

Qのように空のBluebirdプロミスを定義する

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 () {
   // ...
});
36
Fez Vrasta
_var resolver = Promise.defer();
setTimeout(function() {
    resolver.resolve(something); // Resolve the value
}, 5000);
return resolver.promise;
_

この行は documentation でよく使用されます。

これは通常、それを使用するアンチパターンであることに注意してください。しかし、あなたが何をしているのかを知っているなら、Promise.defer()はQの方法と同様のリゾルバを取得する方法です。

ただし、この方法は使用しないでください。 Bluebirdは非推奨になりました。

代わりに、この方法を使用する必要があります。

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

関連ドキュメントのビットを参照してください: Promise.defer() および new Promise()


質問の更新後、問題は次のとおりです。複数の値を解決するために同じ約束を再利用しています。 プロミスは一度しか解決できません。Promise.defer()をプロミスと同じ回数使用する必要があることを意味します。

とはいえ、コードをさらに確認した後、アンチパターンを実際に使用しているようです。 promiseを使用する利点の1つは、エラー処理です。あなたのケースでは、次のコードが必要です:

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

これはユースケースを処理するのに十分なはずです。それは非常に明確であり、という利点もありますreallyエラーを正しく処理します。

23

Florianが良い答えを提供してくれました元の質問のために、Bluebirdでチェーンを開始する方法はいくつかあります。

最も簡単な方法の1つは、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
    });
37

インターネット上のリソースを取得してコンテンツを返すメソッドがあったので、これに遭遇しましたが、接続タイムアウトを処理し、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;
    });
0
Kus

このようなパターンは、あらゆる種類の統合テストに役立ちます。

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
0
Sam Berry