我如何混合承诺和非承诺的功能?

How do I mix promised and non-promised functions?

如何允许有条件的承诺 fire/not 触发并仍然正确解决?

让我解释一下上下文。我要查找三个值。一开始我是

var CustomerReceived = myAjaxLibCall("Customer", "ID", report.CustomerID);
var VehicleReceived  = myAjaxLibCall("Vehicle", "ID", report.VehicleID);
var DealerReceived  = myAjaxLibCall("Dealer", "ID", report.DealerID);

$.when(CustomerReceived,
       VehicleReceived,
       DealerReceived)
.then((Customer,
       Vehicle,
       Dealer) => {
    //do some code here
});

这很好用。但是,AJAX 调用很慢并且需要很多时间。当用户在创建新报告后达到这一点时,他们已经填充了每个项目的列表,这意味着在这种情况下我可以做

var Customer = customerList.findbyID(report.CustomerID);
var Vehicle = vehicleList.findbyID(report.VehicleID);
var Dealer = dealerList.findbyID(report.DealerID);

//do some code here

然后,事实证明,这些列表中的每一个都可能被填充,也可能没有被填充,有时一两个被填充,而其他的则没有。所以理想情况下,如果相应的本地列表不存在,我只想执行每个 ajax 调用。

但是最好的方法是什么?这是我尝试做的,但没有用:

var CustomerReceived = customerList.length === 0
                     ? myAjaxLibCall("Customer", "ID", report.CustomerID)
                     : customerList.findbyID(report.CustomerID);

var VehicleReceived  = vehicleList.length === 0
                     ? myAjaxLibCall("Vehicle", "ID", report.VehicleID)
                     : vehicleList.findbyID(report.VehicleID);

var DealerReceived  = dealerList.length === 0
                    ? myAjaxLibCall("Dealer", "ID", report.DealerID)
                    : dealerList.findbyID(report.DealerID);

$.when(CustomerReceived,
       VehicleReceived,
       DealerReceived)
.then((Customer,
       Vehicle,
       Dealer) => {
    //do some code here
});

等待

您可以使用 await 关键字:

async function someStuff()
{
    var CustomerReceived = customerList.length === 0
                         ? myAjaxLibCall("Customer", "ID", report.CustomerID)
                         : customerList.findbyID(report.CustomerID);

    var VehicleReceived  = vehicleList.length === 0
                         ? myAjaxLibCall("Vehicle", "ID", report.VehicleID)
                         : vehicleList.findbyID(report.VehicleID);

    var DealerReceived  = dealerList.length === 0
                        ? myAjaxLibCall("Dealer", "ID", report.DealerID)
                        : dealerList.findbyID(report.DealerID);

    const Customer = await CustomerReceived;
    const Vehicle = await VehicleReceived;
    const Dealer = await DealerReceived;

    //do some code here
}

根据 MDN:

if the value of the expression following the await operator is not a Promise, it's converted to a resolved Promise.


没有等待

如果你不想使用 async 关键字,你可以使用 Promise.all() 但你需要将你的 promises/functions 存储到一个数组中

var CustomerReceived = customerList.length === 0
                     ? myAjaxLibCall("Customer", "ID", report.CustomerID)
                     : customerList.findbyID(report.CustomerID);

var VehicleReceived  = vehicleList.length === 0
                     ? myAjaxLibCall("Vehicle", "ID", report.VehicleID)
                     : vehicleList.findbyID(report.VehicleID);

var DealerReceived  = dealerList.length === 0
                    ? myAjaxLibCall("Dealer", "ID", report.DealerID)
                    : dealerList.findbyID(report.DealerID);

Promise.all([ CustomerReceived, VehicleReceived, DealerReceived ])
    .then(([ Customer, Vehicle, Dealer ]) => {
        //do some code here
    });

仍然根据 MDN:

If all of the passed-in promises fulfill, or are not promises, the promise returned by Promise.all is fulfilled asynchronously. In all cases, the returned promise is fulfilled with an array containing all the values of the iterable passed as argument (also non-promise values).