将ES6 Promises与JQuery Promises混合使用

Ric*_*ick 5 javascript jquery promise angularjs ecmascript-6

我使用了$ q(Angular.js)并经常在一个.then调用中返回promises .结果是下一个.then呼叫将等待先前的承诺完成.

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

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

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

例:

$.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}
});
Run Code Online (Sandbox Code Playgroud)

我的问题是:

ES6承诺会等待前.then一个承诺解决吗?

Jon*_*ski 23

问题源于尝试PromiseDeferred承诺链中使用本机.

目前(jQuery 1.8 - 2.x),jQuery的定义.then()只能识别库支持链接时自己的类型.

所以,你可以回复一个$.Deferred()承诺:

// ...
.then(function(bot){
  return $.Deferred(function(defer) {
    bot.connect(function(){ defer.resolve(bot); });
  });
}, errorr)
// ...
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用将给定Promise.resolve(thenable)的初始$.Deferred()值转换为本$.ajax()机,Promise以便您在.then()整个链中使用本机,这将识别new Promise()返回(以及a $.Deferred()):

Promise.resolve($.ajax({
  // ...
}))
.then(data => data.token.encoded)
// ...
Run Code Online (Sandbox Code Playgroud)

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

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

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

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