打字稿按顺序执行承诺

时间:2018-05-01 09:13:36

标签: angular typescript es6-promise

我很难在for循环中获得一系列承诺来顺序执行。 我有一个数组和5个函数,都返回承诺。对于数组中的每个元素,我创建了5个参数,每个参数进入每个需要按顺序执行的5个函数,然后再继续执行数组中的下一个项目。 我需要承诺以下列方式执行。

  • 第1项
    • func1的(参数1)
    • 如果func1成功继续func2,则记录错误并停止。
    • 如果func2成功继续func3,则记录错误......
  • 第2项....

等等。

    const array = ['a','b','c','d','e']

    evalParam(param,callback){
        //do things with param 
        callback(true);

    func1(param) {
        return new Promise((resolve, reject) =>{
            this.evalParam(param, resolve);
        });
    }
         .
         .
         .
    func5(param) {
        return new Promise((resolve, reject) =>{
             this.evalParam(param, resolve);
         });
    }
    lastFunc(errors)
    {
       //Do things with errors
       console.log(errors)
    }

    executeChain(array){
        errors : any[] = []
        return new Promise(resolve,reject) => {
            return new Promise(resolve,reject) => {
                for (let item of array){
                    const param1 = this.createParam1(item)
                    const param2 = this.createParam2(item)
                    const param3 = this.createParam3(item)
                    const param4 = this.createParam4(item)
                    const param5 = this.createParam5(item)
                    Promise.resolve()
                        .then(() => { 
                              func1(param1) }
                        .then((val) => {
                            if (val) {
                                func2(param2)
                            } else {
                                errors.push("func1 failed with param: " + param1)
                            }
                               .
                               .
                               .
                        .then((val) => {
                            if (val){
                                func5(param5)
                            else {
                                errors.push("func5 failed with param: " + param5)
                            }
                         })
                } // End for loop
           .then(()=> {
                resolve(errors)
           })
  }

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:1)

我会建议一些事情:

  • 将您的代码分成更小的功能
  • 开始使用async/await,它可以完美地处理此类情况并使您的代码更加清晰

解决方案类似于:

const paramHandlers: Function[] = [
    // func1
    () => {},
    // func2
    () => {}
    // ...
];

async function executeChain(array: any[]): Promise<any> {
    const errors = []; 
    for (const i in array) {
        try {
            // wait for item to be processed or failed with error
            // and continue 
            await executeItem(array[i]);
        } catch (error) {
            // one of param handlers failed with 'error'
            errors.push(error);
        }
    }
    return errors;
}

async function executeItem(arrayValue: any): Promise<any> {
    const params = createParams(arrayValue);
    for (const i in params) {
        const param = params[i];
        // lookup corresponding handler by index
        const paramHandler = paramHandlers[i];
        // execute function and wait for promise to resolve
        // for loop will not continue to next execution until promise resolved
        // if paramHandler's promise will be rejected, 
        // then executeItem will return rejected Promise, having same error
        await paramHandler.apply(param);
    }
}

function createParams(value: any): any[] {
    return [
        /*
         createParam1(value),
         createParam2(value),
         ...
        */
    ];
}

如果您仍想使用promises,则executeItem可能如下所示:

function executeItem(arrayValue: any): Promise<any> {
    const params = createParams(arrayValue);
    return params.reduce((result, param, i) => {
        const paramHandler = paramHandlers[i];
        return result.then(() => paramHandler.apply(param));
    }, Promise.resolve());
}

你可以为executeChain做类似的事情。

请同时查看this question。它包含有关顺序承诺处理的大量信息。

相关问题