在 Typescript 中带有 Observable 的 XMLHttpRequest

Posted

技术标签:

【中文标题】在 Typescript 中带有 Observable 的 XMLHttpRequest【英文标题】:XMLHttpRequest with Observable in Typescript 【发布时间】:2016-10-11 11:54:43 【问题描述】:

当我尝试管理上传文件的 XMLHttpRequest 调用的结果时,我遇到了 tslint 问题。这是我在互联网上找到的当前方法:

// Files upload request
makeFileRequest(url: string, files: Array<File>) 
    return new Promise((resolve, reject) => 
        let formData: any = new FormData()
        let xhr = new XMLHttpRequest()
        for(let file of files) 
            formData.append("uploads[]", file, file.name)
        
        xhr.onreadystatechange = function () 
            if (xhr.readyState === 4) 
                if (xhr.status === 200) 
                    resolve(JSON.parse(xhr.response))
                 else 
                    reject(xhr.response)
                
            
        
        xhr.open("POST", url, true)
        xhr.send(formData)
    )

所以它起作用了,文件正在上传,后端回复 200 响应。但是在我使用这个函数的方法中,我是这样做的:

        this.makeFileRequest("theurl", this.listFiles)
        .map(res => res.json())
            .subscribe(
                res => console.log(res),
                error => console.log("fails")
            )

但是 tslint 在地图点告诉我这个:

TS2339 Property 'map' does not exist on type 'Promise<>'.

所以我认为管理 makeFileRequest 函数会更好,这样它会返回 Observable 而不是 Promise。 为了以防万一,请注意我导入“rxjs/add/operator/map”。

有人知道吗?谢谢!

【问题讨论】:

【参考方案1】:

简单的实现方式:

xhrCall(url, formData, header) 
    return Observable.create(function (observer) 
      let xhr = new XMLHttpRequest();
      xhr.onreadystatechange = function () 
        if (xhr.readyState == 4) 
          if (xhr.status == 200) 
            observer.next(xhr);
           else 
            observer.error(xhr);
          
        
      ;

      xhr.open("POST", url, true);
      xhr.setRequestHeader(header.name, header.value);
      xhr.send(formData);
    );

【讨论】:

【参考方案2】:

mapObservable 的方法,而不是Promise。返回Observable 将修复错误:

makeFileRequest(url: string, files: Array<File>) 
    return Observable.fromPromise(new Promise((resolve, reject) => 
        let formData: any = new FormData()
        let xhr = new XMLHttpRequest()
        for (let file of files) 
            formData.append("uploads[]", file, file.name)
        
        xhr.onreadystatechange = function () 
            if (xhr.readyState === 4) 
                if (xhr.status === 200) 
                    resolve(JSON.parse(xhr.response))
                 else 
                    reject(xhr.response)
                
            
        
        xhr.open("POST", url, true)
        xhr.send(formData)
    ));

错误的解决方法:

Property 'json' does not exist on type ''

https://***.com/a/33919897

别忘了导入Response

import Response from '@angular/http';

【讨论】:

谢谢,它可以满足我的要求 :) 现在我仍然有一个问题,在 .map 行有一个 Property 'json' does not exist on type '',但这是另一个问题 :( 但这很奇怪,我在其他 Observable 映射指令中执行此操作 json() 是来自 Response 的方法,因为通常在 http 中,Observable 返回一个 Response 对象。 我收到此错误:无法在 XMLHttpRequest 上执行打开:无效的 URL 我正在使用 Angular 2,您能帮帮我吗?我很确定这不是 URL,但我是 angular 2 的新手 @MariLuna,不看代码很难说是什么问题。听起来您的网址不正确。 @AndreiZhytkevich 谢谢你,这就是问题所在,我没有放“http”

以上是关于在 Typescript 中带有 Observable 的 XMLHttpRequest的主要内容,如果未能解决你的问题,请参考以下文章

Visual Studio [不是代码] 2019 中带有 TypeScript 和 Node(或 ESM)模块的 ASP.NET 5(核心)网站?

带有 Vetur 的 VSCode 中带有 Typescript 的 NativeScript-Vue:在类型“void”上不存在属性“then”的警报

如何使用 TypeScript 为 Redux-Observable 的 Epic 输入 Actions

在打字稿中带有参数类型的角度 ui-state

打字稿源文件中带有 ts-jest 断点的 vscode-jest

在 ColdFusion 中带有减号的 DollarFormat