Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在像forEach reduce这样的javascript函数中使用promise函数?_Javascript_Typescript_Functional Programming_Promise_Async Await - Fatal编程技术网

如何在像forEach reduce这样的javascript函数中使用promise函数?

如何在像forEach reduce这样的javascript函数中使用promise函数?,javascript,typescript,functional-programming,promise,async-await,Javascript,Typescript,Functional Programming,Promise,Async Await,我使用的承诺函数如下: // WORK let res = {approveList: [], rejectList: [], errorId: rv.errorId, errorDesc: rv.errorDesc}; for (let i = 0; i < rv.copyDetailList.length; i ++) { const item = rv.copyDetailList[i]; const v = await convertCommonInfo(item)

我使用的承诺函数如下:

// WORK
let res = {approveList: [], rejectList: [], errorId: rv.errorId, errorDesc: rv.errorDesc};
for (let i = 0; i < rv.copyDetailList.length; i ++) {
    const item = rv.copyDetailList[i];
    const v = await convertCommonInfo(item);
    if (!item.errorId) {
        res.approveList.push(v);
    } else {
        res.rejectList.push(merge(v, {errorId: item.errorId, errorDesc: item.errorMsg}));
    }
}
error TS2345: Argument of type '(prev: { approveList: any[]; rejectList: any[]; errorId: string; errorDesc: string; }, item: Resp...' is not assignable to parameter of type '(previousValue: { approveList: any[]; rejectList: any[]; errorId: string; errorDesc: string; }, c...'.
Type 'Promise<void>' is not assignable to type '{ approveList: any[]; rejectList: any[]; errorId: string; errorDesc: string; }'.
Property 'approveList' is missing in type 'Promise<void>'.
我发现
forEach
功能无法工作:

// NOT WORK, not wait async function
rv.copyDetailList.forEach(async function(item) {
    const v = await convertCommonInfo(item);
    if (!item.errorId) {
        res.approveList.push(v);
    } else {
        res.rejectList.push(merge(v, {errorId: item.errorId, errorDesc: item.errorMsg}));
    }
});
这不起作用,它只返回init值事实上,这让我很困惑,因为我
正在等待函数,为什么不工作?

即使我想使用
reduce
功能:

// NOT WORK, Typescirpt can not compile
rv.copyDetailList.reduce(async function(prev, item) {
    const v = await convertCommonInfo(item);
    if (!item.errorId) {
        prev.approveList.push(v);
    } else {
        prev.rejectList.push(merge(v, {errorId: item.errorId, errorDesc: item.errorMsg}));
    }
}, res);
但由于我使用的是
Typescript
,所以我得到了如下错误:

// WORK
let res = {approveList: [], rejectList: [], errorId: rv.errorId, errorDesc: rv.errorDesc};
for (let i = 0; i < rv.copyDetailList.length; i ++) {
    const item = rv.copyDetailList[i];
    const v = await convertCommonInfo(item);
    if (!item.errorId) {
        res.approveList.push(v);
    } else {
        res.rejectList.push(merge(v, {errorId: item.errorId, errorDesc: item.errorMsg}));
    }
}
error TS2345: Argument of type '(prev: { approveList: any[]; rejectList: any[]; errorId: string; errorDesc: string; }, item: Resp...' is not assignable to parameter of type '(previousValue: { approveList: any[]; rejectList: any[]; errorId: string; errorDesc: string; }, c...'.
Type 'Promise<void>' is not assignable to type '{ approveList: any[]; rejectList: any[]; errorId: string; errorDesc: string; }'.
Property 'approveList' is missing in type 'Promise<void>'.
error TS2345:type'(prev:{approveList:any[];rejectList:any[];errorId:string;errorDesc:string;},item:Resp…)的参数不能分配给类型的参数(previousValue:{approveList:any[];rejectList:any[];errorId:string;errorDesc:string;},c.。)。
类型“Promise”不能分配给类型“{approveList:any[];rejectList:any[];errorId:string;errorDesc:string;}”。
类型“Promise”中缺少属性“approveList”。
所以我想知道两件事:

  • 为什么
    forEach
    wait无法工作?
  • 我可以在reduce中使用promise函数吗?

  • 您可能正在反向处理此问题。通常,您希望使用
    compose
    组合所有转换,并将该组合函数传递给
    。然后
    承诺的处理程序:

    // assumes curried times and add functions
    let tranformData = _.compose(square, times(2), add(3));
    
    let foo = fetchNumberAsync() // returns a promise of 3
      .then(transformData)
      .catch(err => doSomethingWithError(err));
    
    foo.then(n => console.log(n)); // prints 144 to the console ((3 + 3) * 2) ** 2
    
    与备选方案相比:

    // clear but wasteful
    let foo = fetchNumberAsync()
      .then(n => n + 3)
      .then(n => n * 2)
      .then(n => n ** 2)
    


    使用
    compose
    (尤其是使用
    memoize
    )是一条很好的中间道路。

    为什么forEach Wait不能工作? 您为forEach提供了一个异步函数,但在forEach函数的实现中,它不是等待的。我猜forEach是这样的:

    Array.prototype.forEach = function (func) {
        for (let item of this) {
            func(item);    // Note here, there is no "await" in front of it 
        }
    }
    
    我可以在reduce中使用promise函数吗? 不,您不能使用与上述相同的原因

    通过“co”平滑代码的替代方法如下所示:

    let ret = await rv.copyDetailList.map(co(function * (item) {
        const v = yield convertCommonInfo(item);
        if (!item.errorId) {
            res.approveList.push(v);
        } else {
            res.rejectList.push(merge(v, {errorId: item.errorId, errorDesc: item.errorMsg}));
        }
    }));
    

    如果您的最终目标是在每次迭代同时运行的情况下实现单个遍历,那么可以使用各种库来提供一个“异步遍历”,与您所要查找的内容类似

    一个这样的库是,它提供了一个并行.each迭代器,可以很好地与async/await配合使用

    使用此库,您的代码可能如下所示

    let res = {approveList: [], rejectList: [], errorId: rv.errorId, errorDesc: rv.errorDesc};
    await Parallel.each(rv.copyDetailList, async (item) => {
        var v = await convertCommonInfo(item);
        if (!item.errorId)
            res.approveList.push(v);
        else
            res.rejectList.push(merge(v, {errorId: item.errorId, errorDesc: item.errorMsg}));
    });
    
    可能的重复(对于
    reduce
    ,相同)