繁体   English   中英

将ES6 Promises与JQuery Promises混合使用

[英]Mixing ES6 Promises with JQuery Promises

我已经使用$ Q(Angular.js)和经常一个内返回的承诺.then电话。 结果是下一个.then调用将等待先前的承诺完成。

我现在使用本机es6承诺尝试'promisify'基于回调的库,我无法这样做。

问题是.then链中的下一个值是promise对象 ,而不是该promise的已解析值。 它在解析promise之前调用下一个.then值,只返回最后一个返回值。

无论如何都要等待先前的承诺解决?

例:

$.ajax({
    url: "//localhost:3000/api/tokens",
    type: "POST",
    data: JSON.stringify({
      user: {
        email: 'admin@admin.com',
        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的承诺来解决?

问题源于尝试在Deferred承诺链中使用本机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() $.Deferred()给出的初始$.Deferred()转换为本机Promise以便您在整个链中使用本机.then() ,这将识别返回一个new Promise() (以及$.Deferred() ):

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

或者,您可以尝试jQuery 3.0, 目前处于测试阶段

jQuery.Deferred现在是Promises / A +兼容

jQuery.Deferred对象已经更新,以便与Promises / A +和ES2015 Promises兼容,并通过Promises / A + Compliance Test Suite进行验证 [...]

有了它,您的原始代码段应该按预期工作,无需任何修订。

ES6承诺是否等待之前的承诺解决?

换句话说:ES6承诺永远不会用promise或者then对象调用.then(onFulfilled)函数。 仅使用非承诺值调用Onfulfilled侦听器。

在信任它们之前将jQuery“可以”对象转换为ES6 Promises可以解决问题:

var jqPromise = $.ajax({
    url: "//localhost:3000/api/tokens",
    type: "POST",
    data: JSON.stringify({
      user: {
        email: 'admin@admin.com',
        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

});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM