【问题标题】:Conditional Promise Chaining条件承诺链
【发布时间】:2018-02-25 21:14:19
【问题描述】:

我得到一个 args 数组作为参数,然后根据下面的算法进行大量服务器调用。

  1. 使用 args 数组作为数据发布到端点 /abc。

  2. 遍历 args 数组,

    一个。一次拉 3 个,然后向端点 /pqr 发送 3 个 Get 调用

    b.一旦步骤“2.a”中的 3 个调用成功,将 3 个 Post 调用发送到端点 /def

    c。收集来自步骤 '2.a' 服务器调用的响应并将其推送到数组中。

    d。重复步骤 a,b,c 直到 args 长度。

整个过程的代码片段如下,执行从函数execute(args)开始。

import Promise from 'bluebird';

import request from 'superagent';

// sends a post request to server 
const servercall2 = (args, response) => {

        const req = request
            .post(`${baseUrl}/def`)
            .send(args, response)
            .setAuthHeaders();

        return req.endAsync();
};

// sends a post request to server
const servercall1 = (args) => {

        const req = request
            .post(`${baseUrl}/abc`)
            .send(args)
            .setAuthHeaders();

        return req.endAsync()
            .then((res) => resolve({res}))
            .catch((err) => reject(err));
};

async function makeServerCalls(args, length) {

    // convert args to two dimensional array, chunks of given length [[1,2,3], [4,5,6,], [7,8]]

    const batchedArgs = args.reduce((rows, key, index) => (index % length === 0 ? rows.push([key])
        : rows[rows.length - 1].push(key)) && rows, []);

    const responses = [];

    for (const batchArgs of batchedArgs) {
        responses.push(
            // wait for a chunk to complete, before firing the next chunk of calls
            await Promise.all(

                ***// Error, expected to return a value in arrow function???***
                batchArgs.map((args) => {
                    const req = request
                        .get(`${baseUrl}/pqr`)
                        .query(args)

                    // I want to collect response from above req at the end of all calls.
                    return req.endAsync()
                        .then((response) =>servercall2(args,response)); 
                })
            )
        );
    }

    // wait for all calls to finish
    return Promise.all(responses);
}

export function execute(args) {
    return (dispatch) => {

       servercall1(args)
           .then(makeServerCalls(args, 3))
           .then((responses) => {
                    const serverresponses = [].concat(...responses);
                    console.log(serverresponses);
            });
    };
}

我面临几个问题

  1. 2.c 似乎无法正常工作“从步骤 '2.a' 服务器调用收集响应并将其推送到数组中。”。错误:期望在箭头函数中返回一个值。我在这里做错了什么?请注意,最后我只关心步骤 2.a 的响应。
  2. 这是正确的链接还是可以根据上述要求进行优化?
  3. 我还需要处理其他故障吗?

【问题讨论】:

    标签: javascript ajax reactjs promise axios


    【解决方案1】:

    可能是这样——我认为batchArgs.map 中的每个项目都应该是Promise?然后Promise.all 将等待每个完成:

    batchArgs.map((args) => {
        const req = request
            .get(`${baseUrl}/pqr`)
            .query(args)
    
    
        // Return promise here
        return req.endAsync()
            .then((response) =>servercall2(args,response))
            .then((res) => res);
    })
    

    【讨论】:

    • 正确,但如果我从那里返回它,它将返回来自端点 /def 或 /pqr 的响应。我想从端点 /pqr 收集响应
    • 稍微简化了代码并删除了不必要的承诺。
    【解决方案2】:

    你有一堵墙的文字,所以它变得有点难以破译你真正想要实现的目标,但我会在给出的代码上给我两分钱。

     //Both server calls can be simplified.. no need to
     //wrap in another promise if one is being returned
     const servercall2 = (args, response) => {
           const req = request
                .post(`${baseUrl}/def`)
                .send(args, response)
                .setAuthHeaders();
    
            return req.endAsync();
    };
    
        //Here... you return no value in the function passed to map, thus an 
        //error is being thrown. You need to return a Promise from here so that
        //it can be passed into Promise.all
    
            const allFinished = await Promise.all(
            batchArgs.map((args) => {
                const req = request
                    .get(`${baseUrl}/pqr`)
                    .query(args)
    
                // I want to collect response from above req at the end of all calls.
                return req.endAsync()
            })
           );
           allFinished.then(function(results){
    
           });
    

    【讨论】:

    • 这似乎是正确的,但这里的问题是“我想在所有调用结束时收集来自 req 在 /pqr 端点的服务器的响应”
    • return req.endAsync() .then((response) =>servercall2(args,response)); 将返回来自端点 \pqr 的响应或来自端点 \def 的响应
    • 我稍微编辑了代码,当你等待返回另一个 Promise 时......你能检查一下上面的代码 sn-p 的结果是什么吗?
    • 您缺少 servercall2 调用
    猜你喜欢
    • 2021-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-22
    • 2016-01-07
    • 2016-04-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多