首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >类型记录-在函数返回之前等待承诺解决

类型记录-在函数返回之前等待承诺解决
EN

Stack Overflow用户
提问于 2018-04-18 18:42:58
回答 2查看 24.7K关注 0票数 10

用工作解决方案更新

我从一个函数开始,该函数从表中选择的所有行中获取信息,并将该信息推入堆栈中供以后处理。

代码语言:javascript
运行
复制
for (var i = 0; i < this.selectedItems().length; i++) {
    var row = this.selectedItems()[i];
    let info = this.createFileReqInfo(row.Number(), FileRequestType.AssociatedDoc);
    fileReqInfo.push(info);
}

My Problem:在异步API调用返回值之前,createFileReqInfo函数会返回,因此在返回对象中没有为userCanView获得正确的值。

代码语言:javascript
运行
复制
createFileReqInfo = (reportId: number, fileRequestType: FileRequestType) : any => {
    let fileReq = new FileRequest(reportId, fileRequestType);
    var uCanView = false;
    this.reportModel.getReportSecurity(reportId).done((result) => {
        uCanView = result.CanViewReport;
        var info: {
            fileRequest: FileRequest,
            userCanView: boolean
        } = {
            fileRequest: fileReq,
            userCanView: uCanView
        }
        return info;        
    });
}

编译器不允许我在这里使用await。对于如何在API调用返回之前阻止函数,有什么想法吗?

溶液

我在这里的问题是,这里有几个级别的函数调用,为了创建和解决承诺,我不得不重新工作。调用API的函数类似于建议的解决方案中的某些内容。

代码语言:javascript
运行
复制
createFileReqInfo = (reportId: number, fileRequestType: FileRequestType) : JQueryPromise<any> => {
    let fileReq = new FileRequest(reportId, fileRequestType);
    var uCanView = false;

    var info: {
        fileRequest: FileRequest,
        userCanView: boolean
    } = {
        fileRequest: fileReq,
        userCanView: uCanView
    }

    let dfd: JQueryDeferred<any> = $.Deferred();

    this.reportModel.getReportSecurity(reportId).done((result) => {
        uCanView = result.CanViewReport;
        info.userCanView = uCanView;
        dfd.resolve(info);
    });

    return dfd;
}

这现在回报了一个承诺。我遇到的问题是调用这个函数,因为它遍历所选项目的列表,并排队等待各种报告下载,但只有存在于特定选择中的报表。必须使用答案来找到一种方法,等待所有的承诺解决后再继续。

代码语言:javascript
运行
复制
getFileReqsFromSelectedItems = (view1: boolean, view2: boolean, view3: boolean): JQueryPromise<any> => {
    var fileReqInfo: {
        fileRequest: FileRequest,
        userCanView: boolean
    }[] = [];

    let dfd: JQueryDeferred<any> = $.Deferred();

    let promise: JQueryPromise<any>;
    let promiseArray: JQueryPromise<any>[] = [];

    for (var i = 0; i < this.selectedItems().length; i++) {
        var row = this.selectedItems()[i];

        if( view1 && row.HasView1() ) {
            promise = this.createFileReqInfo(row.Number(), FileRequestType.AssociatedDoc1);
            promiseArray.push(promise);
        }
        if( view2 && row.HasView2() ) {
            promise = this.createFileReqInfo(row.Number(), FileRequestType.AssociatedDoc2);
            promiseArray.push(promise);
        }
        if( view3 && row.HasView3() ) {
            promise = this.createFileReqInfo(row.Number(), FileRequestType.AssociatedDoc3);
            promiseArray.push(promise);
        }
    }

    $.when.apply($, promiseArray).done(function() {
        var promises = arguments;
        for (var j = 0; j < promises.length; j++)
        {
            fileReqInfo.push(promises[j]);
        }
        dfd.resolve(fileReqInfo);
    });

    return dfd;
}

之后,很容易获取返回值的数组并将其传递给下载函数。

代码语言:javascript
运行
复制
downloadReports = () => {
    this.getFileReqsFromSelectedItems(this.view1Check(), this.view2Check(), this.view3Check()).then((fileReqsDetails) => { 
        this.downloadTrialFiles(fileReqsDetails);
    });
}

呼!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-04-18 18:55:58

对于不支持承诺的API,可以使用new Promise自己创建承诺,使用异步调用的结果调用resolve,然后在调用它时使用异步/等待语法。关于承诺的更多信息

代码语言:javascript
运行
复制
interface ReportSecurityInfo {
    fileRequest: FileRequest
    userCanView: boolean
}

createFileReqInfo = (reportId: number, fileRequestType: FileRequestType): Promise<any> => {
    let fileReq = new FileRequest(reportId, fileRequestType);
    var uCanView = false;

    return new Promise((resolve, reject) => {
        this.reportModel.getReportSecurity(reportId).done((result) => {
            uCanView = result.CanViewReport;
            var info: ReportSecurityInfo = {
                fileRequest: fileReq,
                userCanView: uCanView
            }
            resolve(info)
        });
    })
}

// somewhere else...
const info = await this.createFileReqInfo()

为了提高可读性,我还将info类型划分为它自己的接口。

票数 12
EN

Stack Overflow用户

发布于 2018-04-18 18:54:54

您可以从createFileReqInfo返回承诺,然后等待它解决。

代码语言:javascript
运行
复制
for (var i = 0; i < this.selectedItems().length; i++) {
    var row = this.selectedItems()[i];
    let info = await this.createFileReqInfo(row.Number(), FileRequestType.AssociatedDoc);
    fileReqInfo.push(info);
}

代码语言:javascript
运行
复制
for (var i = 0; i < this.selectedItems().length; i++) {
    var row = this.selectedItems()[i];
    this.createFileReqInfo(row.Number(), FileRequestType.AssociatedDoc)
       .then(info => {
               fileReqInfo.push(info);
            });

}

其中createFileReqInfo被定义为:

代码语言:javascript
运行
复制
createFileReqInfo = (reportId: number, fileRequestType: FileRequestType) : Promise<any> => {
  return new Promise( (resolve, reject) => {
    let fileReq = new FileRequest(reportId, fileRequestType);
    var uCanView = false;
    this.reportModel.getReportSecurity(reportId).done((result) => {
        uCanView = result.CanViewReport;
        var info: {
            fileRequest: FileRequest,
            userCanView: boolean
        } = {
            fileRequest: fileReq,
            userCanView: uCanView
        }
        resolve(info);        
    });
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49906865

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档