简体   繁体   English

如何正确地兑现承诺?

[英]How to properly chain promises?

I'm having issues using promises in javascript (es6). 我在javascript(es6)中使用诺言时遇到问题。

So far I've used promises but not so extensively, and in this project I need to chain promises inside others, and make sure to wait one to conclude before I continue with the rest of the tasks. 到目前为止,我已经使用了Promise,但还没有广泛使用,在这个项目中,我需要将Promise内在的Promise连锁起来,并确保在我继续完成其余任务之前要等一个结论。

Here is an example of my code: 这是我的代码示例:


myArray = ['element1', 'element2', /*...*/]
const function1 = () => {
    return function2()
             .then(() => {
                 console.log('first to fire')
                 return myArray
                     .reduce(async(previousPromise, element) => {
                          console.log('reduce', element)
                          await previousPromise
                          return function3(element)
                     }, Promise.resolve())
             })
             .then(() => {
                 console.log('this should fire last but actually fires before the last function3() is done')
             })
}
/*
function1 => the function I'm trying to create, which should return a promise. 

function2 => an external function that I have no control. this function
is asynchronous and returns a promise.

function3 => this is also an asynchronous external function that
returns a promise that I should execute to get what I need. It 
receives as parameter a value which I have in myArray, and it should
execute successively one after the other (for example as if 'element2'
was dependent of 'element1', and so on). 
*/

somehow I'm not chaining this promise properly as the result I'm getting is (myArray with only 2 elements): 由于我得到的结果是某种原因(我的数组只有2个元素),我以某种方式没有正确地链接此诺言:

>first to fire
>reduce element1
>reduce element2
>this should fire last but actually fires before the last function3() is done
>a log I've added inside of function3 which corresponds to 'element1'
>a log I've added inside of function3 which corresponds to 'element2'

So... Basically I need everything to 'wait' until all the promises are done with their work. 所以...基本上,我需要“等待”一切,直到所有诺言都完成了。 How should I properly do that? 我该怎么做呢?

I don't see why your code wouldn't work (most likely the problem is inside function3 , which fulfills its returned promise too early), but you should try to keep it simple: 我不明白为什么您的代码无法正常工作(问题很可能是在function3内部,该function3过早实现了返回的诺言),但是您应该尝试使其简单:

async function function1() {
    await function2();
    console.log('first to fire')
    for (const element of myArray) {
        console.log('loop', element);
        await function3(element);
    }
    console.log('last to fire');
}

You should be using await to get the result from function3. 您应该使用await从function3获取结果。 You also need to use async when declaring your new function. 在声明新功能时,还需要使用async Working example: 工作示例:

 myArray = ['element1', 'element2', 'element3'] const function1 = async() => { return function2() .then(async(results) => { console.log('first to fire with ' + results) return await myArray.reduce(async(accumP, element) => { console.log('reduce', element) return await accumP + await function3(results, element) }, Promise.resolve('')) }) .then((finalResults) => { console.log('this should fire last... and does, with ' + JSON.stringify(finalResults)) }) } const function2 = async() => new Promise((resolve) => setTimeout(() => resolve('foo '), 10)) const function3 = async(prefix, element) => new Promise((resolve) => setTimeout(() => resolve(prefix + element + ' bar, '), 50)) function1() 

As others have noted in the comments, if you are able to use await anyway, you could greatly simplify things for yourself in understanding this by never using then and always using await . 正如其他人在评论中指出的那样,如果您仍然能够使用await ,则可以通过不使用then并始终使用await来极大地简化自己的工作,以了解这一点。

 myArray = ['element1', 'element2', 'element3'] const function1 = async() => { const f2results = await function2() const f3results = await myArray.reduce(async(accumP, element) => { console.log('reduce', element) return await accumP + await function3(f2results, element) }, Promise.resolve('')) console.log('this should fire last... and does, with ' + JSON.stringify(f3results)) } const function2 = async() => new Promise((resolve) => setTimeout(() => resolve('foo '), 10)) const function3 = async(prefix, element) => new Promise((resolve) => setTimeout(() => resolve(prefix + element + ' bar, '), 50)) function1() 

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

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