与 javascript 承诺作斗争
Struggling with javascript Promise
我正在努力实现 javascript 工作承诺。
我正在寻找关于我做错了什么的一两个指示。下面是我的代码。我正在尝试将 loadUserPayRateWrapped()
转换为从数据库获取数据的函数。
我得到的行为是,在 $.getJSON()
有机会获取数据之前,整套包装器代码仍在返回。
正在等待数据请求的函数:
function loadUserPayRateWrapped( projectId )
{
var URI = "/projects/getAssignedResponsibilities?projectId=" + projectId;
$.getJSON( URI, function ( data )
{
if ( data === null )
return getDataFromCookie( "payRate" );
else
{
const employeeId = getDataFromCookie( "empId" );
if ( data[ 0 ].alternatePay === null )
return getDataFromCookie( "payRate" );
var altPayArray = JSON.parse( data[ 0 ].alternatePay );
$.each( altPayArray, function ( idx, element )
{
if ( element.uid == employeeId )
return element.pay;
} );
}
// nothing was found, so return the regular pay rate
return getDataFromCookie( "payRate" );
});
}
包装承诺函数:
function loadUserPayRatePromise( projectId )
{
var payRateProm = new Promise((resolve, reject) =>
{
var payRate = loadUserPayRateWrapped( projectId );
resolve( payRate );
});
payRateProm.then( result => { return payRate } );
}
异步调用方:
async function loadUserPayRate( projectId )
{
try
{
const pay = await loadUserPayRatePromise( projectId );
return pay;
}
catch(error)
{
}
}
来自需要数据的主线的代码:
// add the default pay rate for this user
var payRate = loadUserPayRate( data.projectId );
$( "#hourlyRate" ).val( payRate.toFixed(2) ); //payRate must be populated before this line
我没有使用您绝对可以使用的 $.fetchJSON
,而是使用 window.fetch
来执行此操作。并添加了 async
和 await
以便我们不使用 then
块。
// Added async
async function loadUserPayRateWrapped( projectId )
{
var URI = "/projects/getAssignedResponsibilities?projectId=" + projectId;
// Modified this line
const data = await window.fetch(URI);
if ( data === null )
return getDataFromCookie( "payRate" );
else
{
const employeeId = getDataFromCookie( "empId" );
if ( data[ 0 ].alternatePay === null )
return getDataFromCookie( "payRate" );
var altPayArray = JSON.parse( data[ 0 ].alternatePay );
$.each( altPayArray, function ( idx, element )
{
if ( element.uid == employeeId )
return element.pay;
} );
}
return getDataFromCookie( "payRate" );
}
// Added async
async function loadUserPayRatePromise( projectId )
{
var payRateProm = new Promise((resolve, reject) =>
{
// Added await
var payRate = await loadUserPayRateWrapped( projectId );
resolve( payRate );
});
payRateProm.then( result => { return payRate } );
}
async function loadUserPayRate( projectId )
{
try
{
const pay = await loadUserPayRatePromise( projectId );
return pay;
}
catch(error)
{
}
}
另外,在接下来的版块中
$.each( altPayArray, function ( idx, element ) {
if ( element.uid == employeeId )
return element.pay;
});
return 从函数内部调用 element.pay
将导致它 return 将值传递给内部函数而不是外部函数。因此,您可以
for (const element of altPayArray) {
if ( element.uid == employeeId ) {
return element.pay;
}
}
只需将 $.getJSON
从回调样式“转换”为 Promise 就足够了。
这是我的例子,也许你自己处理过错误。
function loadUserPayRateWrapped(projectId) {
return new Promise((resolve, reject) => { // wrap callback function into a promise
var URI = "/projects/getAssignedResponsibilities?projectId=" + projectId;
$.getJSON(URI, function (data) {
const defaultPayRate = getDataFromCookie("payRate"); // extract to variable to reuse
if (data === null) { // recommend style: if block with {}
return resolve(defaultPayRate);
} else {
const employeeId = getDataFromCookie("empId");
if (data[0].alternatePay === null) {
return resolve(defaultPayRate);
}
var altPayArray = JSON.parse(data[0].alternatePay);
var foundAltPay = altPayArray.find(p => p.uid === employeeId); // why $.each ??
// nothing was found, so return the regular pay rate
return resolve(foundAltPay || defaultPayRate)
}
});
});
}
现在,loadUserPayRateWrapped
return 一个承诺。那么就可以使用Promise风格来调用函数,或者使用async/await
风格:
// Promise style
loadUserPayRateWrapped(data.projectId)
.then(payRate => {
$("#hourlyRate").val(payRate.toFixed(2));
});
// async/await style with IIFE
(async () => {
const payRate = await loadUserPayRateWrapped(data.projectId); // wait
$("#hourlyRate").val(payRate.toFixed(2));
})();
您需要return在loadUserPayRatePromise
的承诺
function loadUserPayRatePromise( projectId )
{
var payRateProm = new Promise((resolve, reject) =>
{
var payRate = loadUserPayRateWrapped( projectId );
resolve( payRate );
});
return payRateProm.then( result => { return payRate } );
}
你想 return 只是你函数的一个承诺,不要命名它。
function loadUserPayRatePromise( projectId ) {
return new Promise((resolve, reject) => {
var payRate = loadUserPayRateWrapped( projectId );
resolve( payRate );
});
}
使它们异步
async function loadUserPayRatePromise( projectId ) {
return new Promise(async (resolve, reject) => {
var payRate = loadUserPayRateWrapped( projectId );
resolve( payRate );
});
}
我正在努力实现 javascript 工作承诺。
我正在寻找关于我做错了什么的一两个指示。下面是我的代码。我正在尝试将 loadUserPayRateWrapped()
转换为从数据库获取数据的函数。
我得到的行为是,在 $.getJSON()
有机会获取数据之前,整套包装器代码仍在返回。
正在等待数据请求的函数:
function loadUserPayRateWrapped( projectId )
{
var URI = "/projects/getAssignedResponsibilities?projectId=" + projectId;
$.getJSON( URI, function ( data )
{
if ( data === null )
return getDataFromCookie( "payRate" );
else
{
const employeeId = getDataFromCookie( "empId" );
if ( data[ 0 ].alternatePay === null )
return getDataFromCookie( "payRate" );
var altPayArray = JSON.parse( data[ 0 ].alternatePay );
$.each( altPayArray, function ( idx, element )
{
if ( element.uid == employeeId )
return element.pay;
} );
}
// nothing was found, so return the regular pay rate
return getDataFromCookie( "payRate" );
});
}
包装承诺函数:
function loadUserPayRatePromise( projectId )
{
var payRateProm = new Promise((resolve, reject) =>
{
var payRate = loadUserPayRateWrapped( projectId );
resolve( payRate );
});
payRateProm.then( result => { return payRate } );
}
异步调用方:
async function loadUserPayRate( projectId )
{
try
{
const pay = await loadUserPayRatePromise( projectId );
return pay;
}
catch(error)
{
}
}
来自需要数据的主线的代码:
// add the default pay rate for this user
var payRate = loadUserPayRate( data.projectId );
$( "#hourlyRate" ).val( payRate.toFixed(2) ); //payRate must be populated before this line
我没有使用您绝对可以使用的 $.fetchJSON
,而是使用 window.fetch
来执行此操作。并添加了 async
和 await
以便我们不使用 then
块。
// Added async
async function loadUserPayRateWrapped( projectId )
{
var URI = "/projects/getAssignedResponsibilities?projectId=" + projectId;
// Modified this line
const data = await window.fetch(URI);
if ( data === null )
return getDataFromCookie( "payRate" );
else
{
const employeeId = getDataFromCookie( "empId" );
if ( data[ 0 ].alternatePay === null )
return getDataFromCookie( "payRate" );
var altPayArray = JSON.parse( data[ 0 ].alternatePay );
$.each( altPayArray, function ( idx, element )
{
if ( element.uid == employeeId )
return element.pay;
} );
}
return getDataFromCookie( "payRate" );
}
// Added async
async function loadUserPayRatePromise( projectId )
{
var payRateProm = new Promise((resolve, reject) =>
{
// Added await
var payRate = await loadUserPayRateWrapped( projectId );
resolve( payRate );
});
payRateProm.then( result => { return payRate } );
}
async function loadUserPayRate( projectId )
{
try
{
const pay = await loadUserPayRatePromise( projectId );
return pay;
}
catch(error)
{
}
}
另外,在接下来的版块中
$.each( altPayArray, function ( idx, element ) {
if ( element.uid == employeeId )
return element.pay;
});
return 从函数内部调用 element.pay
将导致它 return 将值传递给内部函数而不是外部函数。因此,您可以
for (const element of altPayArray) {
if ( element.uid == employeeId ) {
return element.pay;
}
}
只需将 $.getJSON
从回调样式“转换”为 Promise 就足够了。
这是我的例子,也许你自己处理过错误。
function loadUserPayRateWrapped(projectId) {
return new Promise((resolve, reject) => { // wrap callback function into a promise
var URI = "/projects/getAssignedResponsibilities?projectId=" + projectId;
$.getJSON(URI, function (data) {
const defaultPayRate = getDataFromCookie("payRate"); // extract to variable to reuse
if (data === null) { // recommend style: if block with {}
return resolve(defaultPayRate);
} else {
const employeeId = getDataFromCookie("empId");
if (data[0].alternatePay === null) {
return resolve(defaultPayRate);
}
var altPayArray = JSON.parse(data[0].alternatePay);
var foundAltPay = altPayArray.find(p => p.uid === employeeId); // why $.each ??
// nothing was found, so return the regular pay rate
return resolve(foundAltPay || defaultPayRate)
}
});
});
}
现在,loadUserPayRateWrapped
return 一个承诺。那么就可以使用Promise风格来调用函数,或者使用async/await
风格:
// Promise style
loadUserPayRateWrapped(data.projectId)
.then(payRate => {
$("#hourlyRate").val(payRate.toFixed(2));
});
// async/await style with IIFE
(async () => {
const payRate = await loadUserPayRateWrapped(data.projectId); // wait
$("#hourlyRate").val(payRate.toFixed(2));
})();
您需要return在loadUserPayRatePromise
function loadUserPayRatePromise( projectId )
{
var payRateProm = new Promise((resolve, reject) =>
{
var payRate = loadUserPayRateWrapped( projectId );
resolve( payRate );
});
return payRateProm.then( result => { return payRate } );
}
你想 return 只是你函数的一个承诺,不要命名它。
function loadUserPayRatePromise( projectId ) {
return new Promise((resolve, reject) => {
var payRate = loadUserPayRateWrapped( projectId );
resolve( payRate );
});
}
使它们异步
async function loadUserPayRatePromise( projectId ) {
return new Promise(async (resolve, reject) => {
var payRate = loadUserPayRateWrapped( projectId );
resolve( payRate );
});
}