jQuery承诺执行顺序不同于javascript承诺

jQuery承诺执行顺序不同于javascript承诺,javascript,jquery,promise,Javascript,Jquery,Promise,以下Promise的行为与预期一致,return语句中的Promise得到满足,然后在最后一次调用then之前执行then: (new Promise(resolve => resolve(true))) .then(function(){ console.log(0); return new Promise(resolve => setTimeout(resolve, 1000)) .then(function() { console.log

以下
Promise
的行为与预期一致,
return
语句中的
Promise
得到满足,然后在最后一次调用then之前执行
then

(new Promise(resolve => resolve(true)))
.then(function(){
    console.log(0);
    return new Promise(resolve => setTimeout(resolve, 1000))
    .then(function() {
        console.log(1);
    });
}).then(function() {
    console.log(2);
});
结果是

0
1
二,

但是当第一个
Promise
是jQuery
Promise
时,与下面的情况类似

$.post("index.php")
.then(function() {
    console.log(0);
    return new Promise(resolve => setTimeout(resolve, 1000))
    .then(function() {
        console.log(1);
    });
}).then(function() {
    console.log(2);
});
结果是

0 2. 一,

这表示第二个
承诺
没有像标准JavaScript承诺那样传递。
有没有办法强制标准行为

我使用的是jQuery 2.0.0。

jQuery 2不支持,也不能吸收其他实现的承诺(“”)。从回调返回并解析外部承诺的本机承诺不会被等待,而是用作立即实现值。通过检查传递给最终回调的参数可以看到这一点

有没有办法强制标准行为

请参阅基本上只包装
$.post(“index.php”)
,它在
Promise.resolve中启动您的链,以获得一个本地承诺及其所有荣耀(和预期行为)

另一方面(将超时的本机承诺包装在jQuery承诺中),我真的不能推荐,但基本上可以归结为

return $.Deferred(def => promise.then(def.resolve, def.reject)).promise()
jQuery(您使用的版本)可能不适用于es6承诺,我认为它们适用于称为“延迟对象”的东西,因为这不起作用

伟大的凯尔·辛普森(Kyle Simpson)在他的书《你不知道Js:Async和性能》中写到了承诺,这可以帮助你:

“从ES6开始,在事件循环队列的顶部有一个新的概念,称为“作业队列”。您最可能接触到的是承诺的异步行为(参见第3章)。”

由于“新概念分层”,jquery版本不可能很好地将“虚假”承诺与标准承诺混合使用

正在尝试用以下内容覆盖您的$.post:

Promise.resolve($.post("index.php"))
.then(function() {
   console.log(0);
   return new Promise(resolve => setTimeout(resolve, 1000))
     .then(function() {
     console.log(1);
    });
}).then(function() {
 console.log(2);
});
现在,您的承诺链都是es6标准的

凯尔·辛普森书的链接:

还有一个链接,可以查看所有你不知道的JS系列书籍:


jquerys promise似乎不支持扁平化承诺,即
返回新承诺
内的
然后
请仔细阅读问题。他知道根本原因,只是不明白为什么。嗨,凯,我编辑了一点答案,我更好地解释了凯尔·辛普森文本与他的根本原因的关系。太好了!感谢您的贡献:)!不,“新概念分层”根本不是不兼容的根本原因。有许多ES5 promise LIB可以很好地与ES6 promises配合使用。谢谢,Bergi,深入学习总是很好的。我刚刚看到,你对承诺的回答/A+,很高兴知道!!!因此,如果可能的话,最好的方法是继续使用jQuery3。@BenjaminH或其他,是的。但是比起jQuery3承诺,我仍然更喜欢原生承诺,尤其是缺少
Promise.all