简体   繁体   English

Typescript + jQuery Promises = .then类型不匹配

[英]Typescript + jQuery Promises = .then Type mismatch

i'm using Typescript and jQuery Promises and I am experiencing an error with the following code: 我正在使用Typescript和jQuery Promises,我遇到了以下代码的错误:

    var promiseOne = this.myFunc(1);
    var promiseTwo = this.myFunc(2);

    $.when(promiseOne, promiseTwo).then((valFromPromiseOne: number, valFromPromiseTwo: number) =>   //Error here (see below)
    {
        //Use both return values of the promises...
    });

    myFunc(value: number): JQueryPromise<number>
    {
        var dfd = $.Deferred();

        setTimeout(function ()
        {
            dfd.resolve(value);
        }, 1000);

        return dfd.promise();
    }

The error I'm getting is: 我得到的错误是:

    Error   5   Supplied parameters do not match any signature of call target:
        Call signatures of types '(valFromPromiseOne: number, valFromPromiseTwo: number) => void' and '(value: any) => {}' are incompatible:
            Call signature expects 1 or fewer parameters.

I want the function to execute only when both Promises are resolved. 我希望只有在两个Promise都被解析时才能执行该函数。

Am I doing somenthing wrong? 我做错了吗? Is there a different way to achieve what I want? 有没有不同的方法来实现我想要的?

Thanks 谢谢

Finally found out the way to do it. 终于找到了做到这一点的方法。 The second parameter has to be optional. 第二个参数必须是可选的。

$.when(promiseOne, promiseTwo).then((valFromPromiseOne: number, valFromPromiseTwo?: number) =>   //valFromPromiseTwo has to be optional
{
    //Use both return values of the promises...
});

After this change, it is working fine. 在此更改后,它正常工作。

Not sure if it is the right way. 不确定这是不是正确的方法。 But it worked for me. 但它对我有用。

For those still trying to deal with this TypeScript compiler error from the jQuery.d.ts, the generic on $.when will need to be set to 'any' and then you can add typing to the resolving function arguments to resume type safety (and for those fortunate ones... intellisense). 对于那些仍然试图从jQuery.d.ts处理这个TypeScript编译器错误的人来说,$ .when上的泛型需要设置为'any'然后你可以在解析函数参数中添加输入以恢复类型安全性(对于那些幸运的人... intellisense)。

    var promiseOne: JQueryPromise<TypeA> = this.myFunc(1);
    var promiseTwo: JQueryPromise<TypeB> = this.myFunc(2);

    $.when<any>(promiseOne, promiseTwo).then((valFromPromiseOne: TypeA, valFromPromiseTwo: TypeB) => {
           //Use both return values of the promises with Type Safety for TypeA and TypeB...
    });

You're right, the ".d.ts" seems to be incorrect. 你是对的,“。d.ts”似乎是不正确的。 But promises in the jQuery way are not Promises/A+ compliant. 但是jQuery方式的承诺并不符合Promise / A +。

The documentation from jQuery : 来自jQuery文档

In the case where multiple Deferred objects are passed to jQuery.when, the method returns the Promise from a new "master" Deferred object that tracks the aggregate state of all the Deferreds it has been passed. 在将多个Deferred对象传递给jQuery.when的情况下,该方法从新的“master”Deferred对象返回Promise,该对象跟踪它已经传递的所有Deferred的聚合状态。 The method will resolve its master Deferred as soon as all the Deferreds resolve, or reject the master Deferred as soon as one of the Deferreds is rejected. 一旦所有Deferreds解决,该方法将解决其主延期,或者一旦Deferreds被拒绝,该方法将拒绝主延期。 If the master Deferred is resolved, it is passed the resolved values of all the Deferreds that were passed to jQuery.when. 如果解析了主Deferred,则传递传递给jQuery的所有Deferred的已解析值。

It is not the right definition of the method "then()". 它不是“then()”方法的正确定义。 According to the Promises/A+ spec , only the first argument should be used: 根据Promises / A +规范 ,只应使用第一个参数:

2/ If onFulfilled is a function: i/ it must be called after promise is fulfilled, with promise's value as its first argument . 2 /如果onFulfilled是一个函数:i /它必须在promise完成后调用, promise的值作为第一个参数

Modern browsers implement the spec . 现代浏览器实现了规范 The jQuery solution should be avoided, and a compliant polyfill should be preferred. 应该避免使用jQuery解决方案,并且首选兼容的polyfill I suggest to read the article from HTML5 Rocks . 我建议阅读HTML5 Rocks的文章

Although @Jonathan Harrison answer is quite correct, it doesn't cover all possible cases: if the promises are the result of some kind of jQuery ajax call, the received value is not a single value, but an array with three elements: - the expected value - the status of the ajax call - the XHttpRequest object of the ajax call 尽管@Jonathan Harrison的答案是完全正确的,但并未涵盖所有可能的情况:如果promises是某种jQuery ajax调用的结果,则接收的值不是单个值,而是具有三个元素的数组: - 期望值 - ajax调用的状态 - ajax调用的XHttpRequest对象

So, this code fails: 所以,这段代码失败了:

var promiseOne: JQueryPromise<TypeA> = $.ajax(...); // or $.get(), $.post()
var promiseTwo: JQueryPromise<TypeB> = this.myFunc(2);

$.when<any>(promiseOne, promiseTwo).then((
  valFromPromiseOne: TypeA, // oops, is an array [TypeA,string, object]
  valFromPromiseTwo: TypeB // yeah, it's TypeB
) => {

});

The best solution I've found to get it to compile and work it's a custom type, like this: 我发现最好的解决方案是让它编译和工作它是一个自定义类型,如下所示:

type WhenAjaxResponse<T> = [T, string, XMLHttpRequest]

Then, modify the code like this to make it work: 然后,修改这样的代码使其工作:

$.when<any>(promiseOne, promiseTwo).then((
  valFromPromiseOne: WhenAjaxResponse<TypeA>,
  valFromPromiseTwo: TypeB
) => {
  // valFormPromise1[0] is of TypeA
}

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

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