2016-03-28 82 views
2

我已經使用$ q(Angular.js)並且通常會在.then調用中返回承諾。結果是,下一個.then調用將等待先前的承諾完成。混合使用J6承諾的ES6承諾

我現在使用原生es6承諾試圖'promisify'基於回調的庫,我無法這樣做。

問題是,.then鏈中的下一個值是承諾對象,而不是該承諾的已解決值。它在promise解決之前調用下一個.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承諾等前.then的承諾來解決?

+1

角和jQuery不作特別好同牀異夢:

轉換jQuery的「thenable」對象到ES6信任他們可以解決這個問題之前的承諾。在一個角度的應用程序中,你真的應該使用'$ http()',而不是'jQuery.ajax()' –

回答

14

該問題源於試圖在Deferred promises的鏈內使用本地Promise

當前(jQuery 1.8 - 2.x),jQuery的.then()定義只支持鏈接庫中自己的類型。

所以,你可以返回一個$.Deferred()承諾來代替:

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

或者,你可以使用Promise.resolve(thenable)通過$.ajax()給本地Promise初始$.Deferred()轉換,使您在使用本機.then()整個鏈,這將認識到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

在第二個代碼中,'.then(()=> req)我的意思是'req'仍然是jquery的類型.... –

+0

@RoyiNamir本地['.then()'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then)將返回一個新的Promise(),並且該方法被定義爲與其他的「* thenables *」一起工作,比如Deferreds。 –

+0

這段代碼是否可以在jQuery 2和3中使用? –

3

ES6承諾等待以前的。然後承諾解決?

這樣說吧:一個ES6承諾永遠,永遠調用.then(onFulfilled)功能與承諾或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 

});