2016-03-28 8 views
2

私は$ q(Angular.js)を使用しましたが、.thenコールで約束を返すことがよくあります。その結果、次の.thenコールは、前回の約束が完了するまで待つことになりました。JQueryプロミスとES6プロミスを混ぜる

私はネイティブes6の約束を使って、コールバックベースのライブラリを「約束する」ことを試みています。私はそうすることができません。

.thenチェーンの次の値は、その約束の解決された値ではなく約束オブジェクトです。約束が解決される前に、次の.thenの値を呼び出し、最後の戻り値を返します。

これまでの約束を待っていますか?

例:

$.ajax({ 
    url: "//localhost:3000/api/tokens", 
    type: "POST", 
    data: JSON.stringify({ 
     user: { 
     email: '[email protected]', 
     password: 'password123' 
     } 
    }), 
    contentType: "application/json" 
}) 
.then(data => data.token.encoded)   // OK 
.then(token => Farmbot({ token: token })) // OK 
.then(function(bot){      // OK 
    return new Promise(function(resolve, reject) { 
    bot.connect(function(){ resolve(bot); }); 
    }); 
}, errorr) 
.then(function(bot){ // NOT OK! 
    // passes in an unresolved promise object, which is useless. 
    // 
    bot; // => {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined} 
}); 

私の質問は次のとおりです。

ドゥES6の約束は、sが解決することを約束し、前.then」待ちますか?

+1

角度とjQuery特に優れbedfellowsをすることはありません。角型アプリケーションでは、実際には 'jQuery.ajax()'ではなく '$ http()'を使用するべきです。 –

答えて

14

この問題は、ネイティブPromiseDeferred promisesのチェーン内で使用しようとしていることに起因しています。

現在、(jQuery 1.8 - 2.x)のjQueryの定義.then()は、連鎖のサポートでライブラリの独自の型のみを認識します。あなたは全体のネイティブ.then()を使用しているように、あなたはネイティブPromise$.ajax()によって与えられた初期$.Deferred()を変換するPromise.resolve(thenable)を使用することができ、

// ... 
.then(function(bot){ 
    return $.Deferred(function(defer) { 
    bot.connect(function(){ defer.resolve(bot); }); 
    }); 
}, errorr) 
// ... 

をまたは:

だから、あなたの代わりに$.Deferred()約束を返すことができます返されnew Promise()(ならびに$.Deferred())を認識するであろう鎖:

Promise.resolve($.ajax({ 
    // ... 
})) 
.then(data => data.token.encoded) 
// ... 

それとも、あなたはjQueryの3.0、currently in betaを試すことができます。

jQuery.Deferredは今/ A +を約束された互換性の

jQuery.Deferredオブジェクトが約束/ A +とES2015との互換性のために更新されている 約束は、Promises/A+ Compliance Test Suiteで確認されています。 [...]

これで、元のスニペットは改訂なしで期待どおりに動作するはずです。

+0

2番目のコードで '.then(()=> req)'は動作しますか?私は 'req'がまだjqueryの型であることを意味します.... –

+0

@RoyiNamirネイティブ[' .then() '](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then)は '新しいPromise()'を返し、このメソッドはDeferredsのような他の "* thenables *"と連携するように定義されています。 –

+0

このコードはjQuery 2と3の両方で動作しますか? –

3

ES6の約束は、以前の.thenの約束が解決するのを待つか?

このようにそれを置く:ES6の約束決して、これまでは約束またはthenableオブジェクトと.then(onFulfilled)関数を呼び出します。満たされていないリスナーは、約束されていない値でのみ呼び出されます。ES6にjQueryの「thenable」オブジェクトの変換

は、彼らが問題を解決することが信頼する前に約束:

var jqPromise = $.ajax({ 
    url: "//localhost:3000/api/tokens", 
    type: "POST", 
    data: JSON.stringify({ 
     user: { 
     email: '[email protected]', 
     password: 'password123' 
     } 
    }), 
    contentType: "application/json" 
}) 
.then(data => data.token.encoded)   // OK 
.then(token => Farmbot({ token: token })) // OK 

; 

var es6Promise = Promise.resolve(jqPromise); // convert to ES6 promise 

es6Promise.then(function(bot){      // OK 
    return new Promise(function(resolve, reject) { 
    bot.connect(function(){ resolve(bot); }); 
    }); 
}, errorr) 
.then(function(bot){ // will not pass in unfulfilled promise 

    // process bot value 

});