简体   繁体   English

并行调用 async/await 函数

[英]Call async/await functions in parallel

As far as I understand, in ES7/ES2016 putting multiple await 's in code will work similar to chaining .then() with promises, meaning that they will execute one after the other rather than in parallel.据我了解,在 ES7/ES2016 中,在代码中放置多个await的工作方式类似于将.then()与 Promise 链接起来,这意味着它们将一个接一个地执行而不是并行执行。 So, for example, we have this code:因此,例如,我们有以下代码:

await someCall();
await anotherCall();

Do I understand it correctly that anotherCall() will be called only when someCall() is completed?我是否正确理解anotherCall()只有在someCall()完成时才会被调用? What is the most elegant way of calling them in parallel?并行调用它们的最优雅方式是什么?

I want to use it in Node, so maybe there's a solution with async library?我想在 Node 中使用它,所以也许有异步库的解决方案?

EDIT: I'm not satisfied with the solution provided in this question: Slowdown due to non-parallel awaiting of promises in async generators , because it uses generators and I'm asking about a more general use case.编辑:我对这个问题中提供的解决方案不满意: Slowdown due to non-parallel waiting of promises in async generators ,因为它使用了生成器,我在问一个更一般的用例。

You can await on Promise.all() :你可以在Promise.all()上等待:

await Promise.all([someCall(), anotherCall()]);

To store the results:存储结果:

let [someResult, anotherResult] = await Promise.all([someCall(), anotherCall()]);

Note that Promise.all fails fast, which means that as soon as one of the promises supplied to it rejects, then the entire thing rejects.请注意, Promise.all失败很快,这意味着一旦提供给它的承诺之一被拒绝,整个事情就会被拒绝。

 const happy = (v, ms) => new Promise((resolve) => setTimeout(() => resolve(v), ms)) const sad = (v, ms) => new Promise((_, reject) => setTimeout(() => reject(v), ms)) Promise.all([happy('happy', 100), sad('sad', 50)]) .then(console.log).catch(console.log) // 'sad'

If, instead, you want to wait for all the promises to either fulfill or reject, then you can use Promise.allSettled .相反,如果您想等待所有承诺履行或拒绝,那么您可以使用Promise.allSettled Note that Internet Explorer does not natively support this method.请注意,Internet Explorer 本身不支持此方法。

 const happy = (v, ms) => new Promise((resolve) => setTimeout(() => resolve(v), ms)) const sad = (v, ms) => new Promise((_, reject) => setTimeout(() => reject(v), ms)) Promise.allSettled([happy('happy', 100), sad('sad', 50)]) .then(console.log) // [{ "status":"fulfilled", "value":"happy" }, { "status":"rejected", "reason":"sad" }]

Note: If you use Promise.all actions that managed to finish before rejection happen are not rolled back, so you may need to take care of such situation.注意:如果您使用Promise.all在拒绝发生之前设法完成的操作不会回滚,因此您可能需要注意这种情况。 For example if you have 5 actions, 4 quick, 1 slow and slow rejects.例如,如果您有 5 个操作,4 个快速、1 个慢速和慢速拒绝。 Those 4 actions may be already executed so you may need to roll back.这 4 个操作可能已经执行,因此您可能需要回滚。 In such situation consider using Promise.allSettled while it will provide exact detail which action failed and which not.在这种情况下,请考虑使用Promise.allSettled同时它会提供哪些操作失败和哪些操作失败的确切细节。

TL;DR TL; 博士

Use Promise.all for the parallel function calls, the answer behaviors not correctly when the error occurs.使用Promise.all进行并行函数调用,发生错误时应答行为不正确。


First, execute all the asynchronous calls at once and obtain all the Promise objects.首先,一次性执行所有的异步调用,获取所有的Promise对象。 Second, use await on the Promise objects.其次,在Promise对象上使用await This way, while you wait for the first Promise to resolve the other asynchronous calls are still progressing.这样,当您等待第一个Promise解决其他异步调用时,其他异步调用仍在进行中。 Overall, you will only wait for as long as the slowest asynchronous call.总的来说,您只会等待最慢的异步调用。 For example:例如:

// Begin first call and store promise without waiting
const someResult = someCall();

// Begin second call and store promise without waiting
const anotherResult = anotherCall();

// Now we await for both results, whose async processes have already been started
const finalResult = [await someResult, await anotherResult];

// At this point all calls have been resolved
// Now when accessing someResult| anotherResult,
// you will have a value instead of a promise

JSbin example: http://jsbin.com/xerifanima/edit?js,console JSbin 示例: http ://jsbin.com/xerifanima/edit?js,console

Caveat: It doesn't matter if the await calls are on the same line or on different lines, so long as the first await call happens after all of the asynchronous calls.警告: await调用是在同一行还是在不同的行上都没有关系,只要第一个await调用发生所有异步调用之后即可。 See JohnnyHK's comment.请参阅 JohnnyHK 的评论。


Update: this answer has a different timing in error handling according to the @bergi's answer , it does NOT throw out the error as the error occurs but after all the promises are executed.更新:这个回答有错误不同时间处理根据@ BERGI的答案,如发生错误时不会抛出了错误,但所有的承诺都执行之后。 I compare the result with @jonny's tip: [result1, result2] = Promise.all([async1(), async2()]) , check the following code snippet我将结果与[result1, result2] = Promise.all([async1(), async2()])的提示进行比较: [result1, result2] = Promise.all([async1(), async2()]) ,检查以下代码片段

 const correctAsync500ms = () => { return new Promise(resolve => { setTimeout(resolve, 500, 'correct500msResult'); }); }; const correctAsync100ms = () => { return new Promise(resolve => { setTimeout(resolve, 100, 'correct100msResult'); }); }; const rejectAsync100ms = () => { return new Promise((resolve, reject) => { setTimeout(reject, 100, 'reject100msError'); }); }; const asyncInArray = async (fun1, fun2) => { const label = 'test async functions in array'; try { console.time(label); const p1 = fun1(); const p2 = fun2(); const result = [await p1, await p2]; console.timeEnd(label); } catch (e) { console.error('error is', e); console.timeEnd(label); } }; const asyncInPromiseAll = async (fun1, fun2) => { const label = 'test async functions with Promise.all'; try { console.time(label); let [value1, value2] = await Promise.all([fun1(), fun2()]); console.timeEnd(label); } catch (e) { console.error('error is', e); console.timeEnd(label); } }; (async () => { console.group('async functions without error'); console.log('async functions without error: start') await asyncInArray(correctAsync500ms, correctAsync100ms); await asyncInPromiseAll(correctAsync500ms, correctAsync100ms); console.groupEnd(); console.group('async functions with error'); console.log('async functions with error: start') await asyncInArray(correctAsync500ms, rejectAsync100ms); await asyncInPromiseAll(correctAsync500ms, rejectAsync100ms); console.groupEnd(); })();

Update:更新:

The original answer makes it difficult (and in some cases impossible) to correctly handle promise rejections.原始答案使得正确处理承诺拒绝变得困难(在某些情况下是不可能的)。 The correct solution is to use Promise.all :正确的解决方案是使用Promise.all

const [someResult, anotherResult] = await Promise.all([someCall(), anotherCall()]);

Original answer:原答案:

Just make sure you call both functions before you await either one:只需确保在等待任一函数之前调用这两个函数:

// Call both functions
const somePromise = someCall();
const anotherPromise = anotherCall();

// Await both promises    
const someResult = await somePromise;
const anotherResult = await anotherPromise;

There is another way without Promise.all() to do it in parallel:还有另一种没有 Promise.all() 的方法可以并行执行:

First, we have 2 functions to print numbers:首先,我们有两个函数来打印数字:

function printNumber1() {
   return new Promise((resolve,reject) => {
      setTimeout(() => {
      console.log("Number1 is done");
      resolve(10);
      },1000);
   });
}

function printNumber2() {
   return new Promise((resolve,reject) => {
      setTimeout(() => {
      console.log("Number2 is done");
      resolve(20);
      },500);
   });
}

This is sequential:这是顺序的:

async function oneByOne() {
   const number1 = await printNumber1();
   const number2 = await printNumber2();
} 
//Output: Number1 is done, Number2 is done

This is parallel:这是平行的:

async function inParallel() {
   const promise1 = printNumber1();
   const promise2 = printNumber2();
   const number1 = await promise1;
   const number2 = await promise2;
}
//Output: Number2 is done, Number1 is done

I've created a gist testing some different ways of resolving promises, with results.我创建了一个 gist,测试了一些解决承诺的不同方法,并给出了结果。 It may be helpful to see the options that work.查看有效的选项可能会有所帮助。

Edit: Gist content as per Jin Lee 's comment编辑:根据Jin Lee的评论要点内容

// Simple gist to test parallel promise resolution when using async / await

function promiseWait(time) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(true);
    }, time);
});
}


async function test() {
    return [
    await promiseWait(1000),
    await promiseWait(5000),
    await promiseWait(9000),
    await promiseWait(3000),
    ]
}

async function test2() {
    return {
        'aa': await promiseWait(1000),
        'bb': await promiseWait(5000),
        'cc': await promiseWait(9000),
        'dd': await promiseWait(3000),
    }
}

async function test3() {
    return await {
        'aa': promiseWait(1000),
        'bb': promiseWait(5000),
        'cc': promiseWait(9000),
        'dd': promiseWait(3000),
    }
}

async function test4() {
    const p1 =  promiseWait(1000);
    const p2 =  promiseWait(5000);
    const p3 =  promiseWait(9000);
    const p4 =  promiseWait(3000);
    return {
        'aa': await p1,
        'bb': await p2,
        'cc': await p3,
        'dd': await p4,
    };
}

async function test5() {
    return await Promise.all([
                             await promiseWait(1000),
                             await promiseWait(5000),
                             await promiseWait(9000),
                             await promiseWait(3000),
                             ]);
}

async function test6() {
    return await Promise.all([
                             promiseWait(1000),
                             promiseWait(5000),
                             promiseWait(9000),
                             promiseWait(3000),
                             ]);
}

async function test7() {
    const p1 =  promiseWait(1000);
    const p2 =  promiseWait(5000);
    const p3 =  promiseWait(9000);
    return {
        'aa': await p1,
        'bb': await p2,
        'cc': await p3,
        'dd': await promiseWait(3000),
    };
}

let start = Date.now();

test().then((res) => {
    console.log('Test Done, elapsed', (Date.now() - start) / 1000, res);

    start = Date.now();
    test2().then((res) => {
        console.log('Test2 Done, elapsed', (Date.now() - start) / 1000, res);

        start = Date.now();
        test3().then((res) => {
            console.log('Test3 Done, elapsed', (Date.now() - start) / 1000, res);

            start = Date.now();
            test4().then((res) => {
                console.log('Test4 Done, elapsed', (Date.now() - start) / 1000, res);

                start = Date.now();
                test5().then((res) => {
                    console.log('Test5 Done, elapsed', (Date.now() - start) / 1000, res);

                    start = Date.now();
                    test6().then((res) => {
                        console.log('Test6 Done, elapsed', (Date.now() - start) / 1000, res);
                    });

                    start = Date.now();
                    test7().then((res) => {
                        console.log('Test7 Done, elapsed', (Date.now() - start) / 1000, res);
                    });
                });
            });

        });
    });

});
/*
Test Done, elapsed 18.006 [ true, true, true, true ]
Test2 Done, elapsed 18.009 { aa: true, bb: true, cc: true, dd: true }
Test3 Done, elapsed 0 { aa: Promise { <pending> },
  bb: Promise { <pending> },
  cc: Promise { <pending> },
  dd: Promise { <pending> } }
Test4 Done, elapsed 9 { aa: true, bb: true, cc: true, dd: true }
Test5 Done, elapsed 18.008 [ true, true, true, true ]
Test6 Done, elapsed 9.003 [ true, true, true, true ]
Test7 Done, elapsed 12.007 { aa: true, bb: true, cc: true, dd: true }
*/

In my case, I have several tasks I want to execute in parallel, but I need to do something different with the result of those tasks.就我而言,我有几个要并行执行的任务,但我需要对这些任务的结果做一些不同的事情。

function wait(ms, data) {
    console.log('Starting task:', data, ms);
    return new Promise(resolve => setTimeout(resolve, ms, data));
}

var tasks = [
    async () => {
        var result = await wait(1000, 'moose');
        // do something with result
        console.log(result);
    },
    async () => {
        var result = await wait(500, 'taco');
        // do something with result
        console.log(result);
    },
    async () => {
        var result = await wait(5000, 'burp');
        // do something with result
        console.log(result);
    }
]

await Promise.all(tasks.map(p => p()));
console.log('done');

And the output:和输出:

Starting task: moose 1000
Starting task: taco 500
Starting task: burp 5000
taco
moose
burp
done

The intuitive solution 直观的解决方案

 function wait(ms, data) { console.log('Starting task:', data, ms); return new Promise( resolve => setTimeout(resolve, ms, data) ); } (async function parallel() { // step 1 - initiate all promises console.log('STARTING') let task1 = wait(2000, 'parallelTask1') // PS: see Exception handling below let task2 = wait(500, 'parallelTask2') let task3 = wait(1000, 'parallelTask3') // step 2 - await all promises console.log('WAITING') task1 = await task1 task2 = await task2 task3 = await task3 // step 3 - all results are 100% ready console.log('FINISHED') console.log('Result:', task1, task2, task3) })() 

  1. This will execute the promises one by one, but instantly and they will continue running simultaneously. 这将一个接一个地执行承诺,但立即执行,它们将继续同时运行。
  2. This is where we pause further code execution and wait for them to finish. 这是我们暂停进一步的代码执行并等待它们完成的地方。 It doesn't matter on the order and which one resolves first. 顺序无关紧要,先解决的是哪一个。 The code will not continue to step 3 before all of them resolve. 在所有代码都解决之前,该代码将不会继续执行步骤3。 If the first takes the longest, it will not have to wait any longer for the second as it would have been fulfilled by the time the code gets there. 如果第一个使用的时间最长,则不必再等待第二个,因为在代码到达那里之前它已经完成了。
  3. It is done, last of the promises have resolved and the code execution completed last await call. 完成,最后的承诺已解决,最后await调用完成了代码执行。


With ES6 you can even do this in step 2, after executed initiation 使用ES6,您甚至可以在执行启动后的第2步中执行此操作

 [task1, task2, task3] = [await task1, await task2, await task3] 


PS: You can also await inside calculations PS:您也可以等待内部计算

 let five = getAsyncFive() let ten = getAsyncTen() let result = await five * await ten 

*note that it is not the same as let result = await getAsyncFive() * await getAsyncTen() as this will not run the async tasks in parallel! *请注意,它与let result = await getAsyncFive() * await getAsyncTen()因为这不会并行运行异步任务!


exception handling 异常处理

In the snippet below, the .catch(e => e) catches an error and allows the chain to continue, allowing the promise to resolve , instead of rejecting . 在下面的代码段中, .catch(e => e)捕获错误并允许链继续进行,从而使promise得以解决而不是拒绝 Without the catch , the code would throw an Unhandled Exception and the function would exit early. 如果没有catch ,则代码将引发未处理的异常,并且该函数将提前退出。

 const wait = (ms, data) => log(ms,data) || new Promise( resolve => setTimeout(resolve, ms, data) ) const reject = (ms, data) => log(ms,data) || new Promise( (r, reject) => setTimeout(reject, ms, data) ) const e = e => 'err-' + e const l = l => (console.log('Done:', l), l) const log = (ms, data) => console.log('Started', data, ms) ;(async function parallel() { let task1 = reject(500, 'parallelTask1').catch(e).then(l) let task2 = wait(2000, 'parallelTask2').catch(e).then(l) let task3 = reject(1000, 'parallelTask3').catch(e).then(l) console.log('WAITING') task1 = await task1 task2 = await task2 task3 = await task3 console.log('FINISHED', task1, task2, task3) })() 

The second snippet is not handled and the function will fail. 第二个代码段未处理,功能将失败。
You can also open Devtools and see the errors in Console output. 您也可以打开Devtools并在控制台输出中查看错误。

 const wait = (ms, data) => log(ms,data) || new Promise( resolve => setTimeout(resolve, ms, data) ) const reject = (ms, data) => log(ms,data) || new Promise( (r, reject) => setTimeout(reject, ms, data) ) const e = e => 'err-' + e const l = l => (console.log('Done:', l), l) const log = (ms, data) => console.log('Started', data, ms) console.log('here1') ;(async function parallel() { let task1 = reject(500, 'parallelTask1').then(l) // catch is removed let task2 = wait(2000, 'parallelTask2').then(l) let task3 = reject(1000, 'parallelTask3').then(l) console.log('WAITING') task1 = await task1 task2 = await task2 task3 = await task3 console.log('FINISHED', task1, task2, task3) })() console.log('here2') // Note: "FINISHED" will not run 

await Promise.all([someCall(), anotherCall()]);等待 Promise.all([someCall(), anotherCall()]); as already mention will act as a thread fence (very common in parallel code as CUDA), hence it will allow all the promises in it to run without blocking each other, but will prevent the execution to continue until ALL are resolved.如前所述,它将充当线程栅栏(在作为 CUDA 的并行代码中非常常见),因此它将允许其中的所有 promise 运行而不会相互阻塞,但会阻止执行继续,直到解决所有问题。

another approach that is worth to share is the Node.js async that will also allow you to easily control the amount of concurrency that is usually desirable if the task is directly linked to the use of limited resources as API call, I/O operations, etc.另一种值得分享的方法是 Node.js 异步,如果任务直接链接到有限资源的使用,如 API 调用、I/O 操作,它也将允许您轻松控制通常需要的并发量,等等。

// create a queue object with concurrency 2
var q = async.queue(function(task, callback) {
  console.log('Hello ' + task.name);
  callback();
}, 2);

// assign a callback
q.drain = function() {
  console.log('All items have been processed');
};

// add some items to the queue
q.push({name: 'foo'}, function(err) {
  console.log('Finished processing foo');
});

q.push({name: 'bar'}, function (err) {
  console.log('Finished processing bar');
});

// add some items to the queue (batch-wise)
q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function(err) {
  console.log('Finished processing item');
});

// add some items to the front of the queue
q.unshift({name: 'bar'}, function (err) {
  console.log('Finished processing bar');
});

Credits to the Medium article autor ( read more )归功于 Medium 文章作者( 阅读更多

    // A generic test function that can be configured 
    // with an arbitrary delay and to either resolve or reject
    const test = (delay, resolveSuccessfully) => new Promise((resolve, reject) => setTimeout(() => {
        console.log(`Done ${ delay }`);
        resolveSuccessfully ? resolve(`Resolved ${ delay }`) : reject(`Reject ${ delay }`)
    }, delay));

    // Our async handler function
    const handler = async () => {
        // Promise 1 runs first, but resolves last
        const p1 = test(10000, true);
        // Promise 2 run second, and also resolves
        const p2 = test(5000, true);
        // Promise 3 runs last, but completes first (with a rejection) 
        // Note the catch to trap the error immediately
        const p3 = test(1000, false).catch(e => console.log(e));
        // Await all in parallel
        const r = await Promise.all([p1, p2, p3]);
        // Display the results
        console.log(r);
    };

    // Run the handler
    handler();
    /*
    Done 1000
    Reject 1000
    Done 5000
    Done 10000
    */

Whilst setting p1, p2 and p3 is not strictly running them in parallel, they do not hold up any execution and you can trap contextual errors with a catch.虽然设置 p1、p2 和 p3 并不是严格并行运行它们,但它们不会阻止任何执行,您可以使用 catch 捕获上下文错误。

You can call multiple asynchronous functions without awaiting them.您可以调用多个异步函数而无需等待它们。 This will execute them in parallel.这将并行执行它们。 While doing so, save the returned promises in variables, and await them at some point either individually or using Promise.all() and process the results.这样做时,将返回的承诺保存在变量中,并在某个时候单独或使用 Promise.all() 等待它们并处理结果。

You can also wrap the function calls with try...catch to handle failures of individual asynchronous actions and provide fallback logic.您还可以使用 try...catch 包装函数调用以处理单个异步操作的失败并提供回退逻辑。

Here's an example: Observe the logs, the logs printed at the beginning of execution of the individual asynchronous functions get printed immediately even though the first function takes 5 seconds to resolve.这是一个例子:观察日志,即使第一个函数需要 5 秒来解析,在单个异步函数执行开始时打印的日志也会立即打印。

 function someLongFunc () { return new Promise((resolve, reject)=> { console.log('Executing function 1') setTimeout(resolve, 5000) }) } function anotherLongFunc () { return new Promise((resolve, reject)=> { console.log('Executing function 2') setTimeout(resolve, 5000) }) } async function main () { let someLongFuncPromise, anotherLongFuncPromise const start = Date.now() try { someLongFuncPromise = someLongFunc() } catch (ex) { console.error('something went wrong during func 1') } try { anotherLongFuncPromise = anotherLongFunc() } catch (ex) { console.error('something went wrong during func 2') } await someLongFuncPromise await anotherLongFuncPromise const totalTime = Date.now() - start console.log('Execution completed in ', totalTime) } main()

This can be accomplished with Promise.allSettled() , which is similar to Promise.all() but without the fail-fast behavior. 这可以通过Promise.allSettled()来实现,它类似于Promise.all()但没有快速失败行为。

async function failure() {
    throw "Failure!";
}

async function success() {
    return "Success!";
}

const [failureResult, successResult] = await Promise.allSettled([failure(), success()]);

console.log(failureResult); // {status: "rejected", reason: "Failure!"}
console.log(successResult); // {status: "fulfilled", value: "Success!"}

Note : This is a bleeding edge feature with limited browser support, so I strongly recommend including a polyfill for this function. 注意 :这是一项最新功能,浏览器支持有限,因此,我强烈建议为此功能包括一个polyfill。

This can be accomplished with Promise.allSettled() , which is similar to Promise.all() but without the fail-fast behavior.这可以通过Promise.allSettled()来完成,它类似于Promise.all()但没有快速故障行为。

async function Promise1() {
    throw "Failure!";
}

async function Promise2() {
    return "Success!";
}

const [Promise1Result, Promise2Result] = await Promise.allSettled([Promise1(), Promise2()]);

console.log(Promise1Result); // {status: "rejected", reason: "Failure!"}
console.log(Promise2Result); // {status: "fulfilled", value: "Success!"}

Note: This is a bleeding edge feature with limited browser support, so I strongly recommend including a polyfill for this function.注意:这是一个有限浏览器支持的前沿特性,所以我强烈建议为这个 function 包含一个 polyfill。

For Readers in 2021 who needs Front-end New Stars's way: 2021年需要前端新星之路的读者:

The following is the most beautiful front-end API gateway code ever exist, it calls three different services in parallel, then use one of the result to loop-call anther service, ProblemService .以下是有史以来最漂亮的前端 API 网关代码,它并行调用三个不同的服务,然后使用结果之一循环调用另一个服务ProblemService

Notice that how I use await , async , and Promise.all that beats entire StackOverflow.请注意,我如何使用awaitasyncPromise.all击败了整个 StackOverflow。

class ExamScoreboardService {
    getExamScoreboard(examId) {
        return Promise.all([
            examService.getExaminees(examId),
            examService.getExamOverview(examId),
            examService.getExamScores(examId),
        ])
            .then(async ([examinees, exam, examScores]) => {
                const out = {}
                await Promise.all(exam.questions.map(async q =>
                    problemService.getProblemById(q.problemId).then(problem => out[q.problemId] = problem.testcases.length)))
                return [examinees, exam, examScores, out]
            })
            .then(values => {
                const [examinees, exam, examScores, totalTestcasesOf] = values;
                return new ExamScoreboard({examinees, exam, examScores, totalTestcasesOf});
            })
    }
}

I create a helper function waitAll, may be it can make it sweeter.我创建了一个辅助函数waitAll,也许它可以让它更甜。 It only works in nodejs for now, not in browser chrome.它目前仅适用于nodejs不适用于浏览器 chrome。

    //const parallel = async (...items) => {
    const waitAll = async (...items) => {
        //this function does start execution the functions
        //the execution has been started before running this code here
        //instead it collects of the result of execution of the functions

        const temp = [];
        for (const item of items) {
            //this is not
            //temp.push(await item())
            //it does wait for the result in series (not in parallel), but
            //it doesn't affect the parallel execution of those functions
            //because they haven started earlier
            temp.push(await item);
        }
        return temp;
    };

    //the async functions are executed in parallel before passed
    //in the waitAll function

    //const finalResult = await waitAll(someResult(), anotherResult());
    //const finalResult = await parallel(someResult(), anotherResult());
    //or
    const [result1, result2] = await waitAll(someResult(), anotherResult());
    //const [result1, result2] = await parallel(someResult(), anotherResult());

I vote for:我投票赞成:

await Promise.all([someCall(), anotherCall()]);

Be aware of the moment you call functions, it may cause unexpected result:注意调用函数的那一刻,可能会导致意想不到的结果:

// Supposing anotherCall() will trigger a request to create a new User

if (callFirst) {
  await someCall();
} else {
  await Promise.all([someCall(), anotherCall()]); // --> create new User here
}

But following always triggers request to create new User但是以下总是触发创建新用户的请求

// Supposing anotherCall() will trigger a request to create a new User

const someResult = someCall();
const anotherResult = anotherCall(); // ->> This always creates new User

if (callFirst) {
  await someCall();
} else {
  const finalResult = [await someResult, await anotherResult]
}

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

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