为什么承诺链不能按预期工作(链接任务)

时间:2017-10-28 13:18:00

标签: javascript ecmascript-6 promise es6-promise chain

使用带有'.then'的链条有什么好处,如果它不像预期的那样工作:

rm(list=ls())

library(deSolve)

l <- 0.5 # bone 1/2 thickness (cm)
x_vec <- c(0.05, 0.15, 0.25, 0.30, 0.45) # distance along the bone (cm)
U48meas <- c(1.195, 1.197, 1.199, 1.201, 1.209) # measured (234U/238U)
Th0U8meas <- c(0.43, 0.44, 0.46, 0.47, 0.51) # measured (230Th/238U)

paraminit <- c(5*10e-13, 10e3, 1.2) # initial parameters: D/R, age (yr) and (234U/238U) at the surface
lowerbound <- c(1e-14, 1e4, 1) # minimum values: D/R, age (yr) and (234U/238U) at the surface
upperbound <- c(1e-12, 60e3, 1.3) # maximum values: D/R, age (yr) and (234U/238U) at the surface

A1_0 <- 0.025 # (238U) activity at the surface of the bone (disintegrations per second)

l234 <- 2.8262e-6/(365.25*24*3600) # 234U decay constant (s-1)
l230 <- 9.1577e-6/(365.25*24*3600) # 230Th decay constant (s-1)

length_series <- 100 # number of n in the series sum

funmin <- function(x) {
  K <- x[1] # D/R diffusion coefficient/volumetric equilibirum constant
  t <- x[2] # age in yr
  t <- t*(365.25*24*3600) # convert age to seconds
  U48_0 <- x[3] # (234U/238U) at the surface
  A2_0 <- U48_0*A1_0 # (234U) activity at the surface (disintegrations per second)
  DA2_0 <- A2_0 - A1_0 # (234U) activity excess at the surface of the bone (disintegrations per second)

  # create vectors
  series238 <- vector(mode="numeric", length=length_series+1)
  series234 <- vector(mode="numeric", length=length_series+1)
  series230 <- vector(mode="numeric", length=length_series+1)
  beta234 <- vector(mode="numeric", length=length_series+1)
  beta230 <- vector(mode="numeric", length=length_series+1)
  gamma <- vector(mode="numeric", length=length_series+1)
  A1 <- vector(mode="numeric", length=length(x_vec))
  DA2 <- vector(mode="numeric", length=length(x_vec))
  A3 <- vector(mode="numeric", length=length(x_vec))
  f <- vector(mode="numeric", length=length(x_vec))

  i <- 0

  for (x in x_vec){
    for (n in 0:length_series){
      # series238[n+1] <- (-1)^n/(2*n + 1)*exp(-K*((2*n + 1)^2)*pi^2*t/(4*l^2))*cos((2*n + 1)/2*pi*x/l)
      series238[n+1] <- (-1)/(2*n + 1)*exp(-K*((2*n + 1)^2)*pi^2*t/(4*l^2))*cos((2*n + 1)/2*pi*x/l)
      beta234[n+1] <- 1 + 4*l234*(l^2)/((2*n + 1)^2)*pi^2*K
      beta230[n+1] <- l230 - l234 - K*(2*n + 1)^2*pi^2/(4*l^2)
      gamma[n+1] <- l230*(1/(beta230[n+1] + l234) + (U48_0 - 1)*exp(-l234*t)/(beta234[n+1]*beta230[n+1]))
      # series234[n+1] <- (-1)^n/((2*n + 1)*beta234[n+1])*exp(-l234*t-K*(2*n + 1)^2*pi^2*t/(4*l^2))*cos((2*n + 1)/2*pi*x/l)
      # series230[n+1] <- (-1)^n/(2*n + 1)*gamma[n+1]*exp(-K*(2*n + 1)^2*pi^2*t/(4*l^2))*cos((2*n + 1)/2*pi*x/l)
      series234[n+1] <- (-1)/((2*n + 1)*beta234[n+1])*exp(-l234*t-K*(2*n + 1)^2*pi^2*t/(4*l^2))*cos((2*n + 1)/2*pi*x/l)
      series230[n+1] <- (-1)/(2*n + 1)*gamma[n+1]*exp(-K*(2*n + 1)^2*pi^2*t/(4*l^2))*cos((2*n + 1)/2*pi*x/l)
    }
    sum_series238 <- sum(series238)  
    sum_series234 <- sum(series234)  
    sum_series230 <- sum(series230)
    i <- i+1
    A1[i] <- A1_0*(1 - 4/pi*sum_series238) # (238U) activity (disintegrations per second)
    DA2[i] <- DA2_0*(cosh(x*(l234/K)^0.5)/(cosh(l*l234/K)^0.5) - 4/pi*sum_series234) # (234U) activity excess (disintegrations per second)

    # calculate 'f' used to calculate A3
    t0 <- 0
    series230_0 <- vector(mode="numeric", length=length_series+1)
    beta234_0 <- vector(mode="numeric", length=length_series+1)
    beta230_0 <- vector(mode="numeric", length=length_series+1)
    gamma_0 <- vector(mode="numeric", length=length_series+1)
    for (n in 0:length_series){
      beta234_0[n+1] <- 1 + 4*l234*(l^2)/((2*n + 1)^2)*pi^2*K
      beta230_0[n+1] <- l230 - l234 - K*(2*n + 1)^2*pi^2/(4*l^2)
      gamma_0[n+1] <- l230*(1/(beta230[n+1] + l234) + (U48_0 - 1)*exp(-l234*t0)/(beta234[n+1]*beta230[n+1]))
      # series230_0[n+1] <- (-1)^n/(2*n + 1)*gamma[n+1]*exp(-K*(2*n + 1)^2*pi^2*t0/(4*l^2))*cos((2*n + 1)/2*pi*x/l)
      series230_0[n+1] <- (-1)/(2*n + 1)*gamma[n+1]*exp(-K*(2*n + 1)^2*pi^2*t0/(4*l^2))*cos((2*n + 1)/2*pi*x/l)
    }
    sum_series230_0 <- sum(series230_0)
    f[i] <- - A1_0*(1 + (U48_0 - 1)*cosh(x*(l234/K)^0.5)/(cosh(l*(l234/K)^0.5) - 4/pi*sum_series230_0))*exp(-l230*t)
    A3[i] <- f[i] + A1_0*(1 + (U48_0 - 1)*cosh(x*(l234/K)^0.5)/(cosh(l*(l234/K)^0.5) - 4/pi*sum_series230)) # (230Th) activity (disintegrations per second)
  }
  A2 <- DA2 + A1 # (234U) activity (disintegrations per second)
  U48calc <- A2/A1 # (234U/238U)
  Th0U8calc <- A3/A1 # (230Th/238U)
  Th0U4calc <- A3/A2 # (230Th/234U)
  fmin <- sum((U48calc - U48meas)^2 + (Th0U8calc - Th0U8meas)^2 ) # function to minimise
}

sol <- optim(paraminit, funmin, method = "L-BFGS-B",
             lower = lowerbound, upper = upperbound)

print(sol) # display result of minimisation

#########################################################
# calculate ratios with solutions from minimisation

x_vec <- c(0.05, 0.15, 0.25, 0.30, 0.45)

K <- sol$par[1] # D/R diffusion coefficient/volumetric equilibirum constant
t <- sol$par[2] # age in yr
t <- t*(365.25*24*3600)
U48_0 <- sol$par[3]
A2_0 <- U48_0*A1_0
DA2_0 <- A2_0 - A1_0 # (234U) excess at the surface of the bone (disintegrations per second)

series238 <- vector(mode="numeric", length=length_series+1)
series234 <- vector(mode="numeric", length=length_series+1)
series230 <- vector(mode="numeric", length=length_series+1)
beta234 <- vector(mode="numeric", length=length_series+1)
beta230 <- vector(mode="numeric", length=length_series+1)
gamma <- vector(mode="numeric", length=length_series+1)
A1 <- vector(mode="numeric", length=length(x_vec))
DA2 <- vector(mode="numeric", length=length(x_vec))
A3 <- vector(mode="numeric", length=length(x_vec))
f <- vector(mode="numeric", length=length(x_vec))

i <- 0

for (x in x_vec){
  for (n in 0:length_series){
    # series238[n+1] <- (-1)^n/(2*n + 1)*exp(-K*((2*n + 1)^2)*pi^2*t/(4*l^2))*cos((2*n + 1)/2*pi*x/l)
    series238[n+1] <- (-1)/(2*n + 1)*exp(-K*((2*n + 1)^2)*pi^2*t/(4*l^2))*cos((2*n + 1)/2*pi*x/l)
    beta234[n+1] <- 1 + 4*l234*(l^2)/((2*n + 1)^2)*pi^2*K
    beta230[n+1] <- l230 - l234 - K*(2*n + 1)^2*pi^2/(4*l^2)
    gamma[n+1] <- l230*(1/(beta230[n+1] + l234) + (U48_0 - 1)*exp(-l234*t)/(beta234[n+1]*beta230[n+1]))
    # series234[n+1] <- (-1)^n/((2*n + 1)*beta234[n+1])*exp(-l234*t-K*(2*n + 1)^2*pi^2*t/(4*l^2))*cos((2*n + 1)/2*pi*x/l)
    # series230[n+1] <- (-1)^n/(2*n + 1)*gamma[n+1]*exp(-K*(2*n + 1)^2*pi^2*t/(4*l^2))*cos((2*n + 1)/2*pi*x/l)
    series234[n+1] <- (-1)/((2*n + 1)*beta234[n+1])*exp(-l234*t-K*(2*n + 1)^2*pi^2*t/(4*l^2))*cos((2*n + 1)/2*pi*x/l)
    series230[n+1] <- (-1)/(2*n + 1)*gamma[n+1]*exp(-K*(2*n + 1)^2*pi^2*t/(4*l^2))*cos((2*n + 1)/2*pi*x/l)
  }
  sum_series238 <- sum(series238)  
  sum_series234 <- sum(series234)  
  sum_series230 <- sum(series230)
  i <- i+1
  A1[i] <- A1_0*(1 - 4/pi*sum_series238)
  DA2[i] <- DA2_0*(cosh(x*(l234/K)^0.5)/(cosh(l*l234/K)^0.5) - 4/pi*sum_series234)

  t0 <- 0
  series230_0 <- vector(mode="numeric", length=length_series+1)
  beta234_0 <- vector(mode="numeric", length=length_series+1)
  beta230_0 <- vector(mode="numeric", length=length_series+1)
  gamma_0 <- vector(mode="numeric", length=length_series+1)
  for (n in 0:length_series){
    beta234_0[n+1] <- 1 + 4*l234*(l^2)/((2*n + 1)^2)*pi^2*K
    beta230_0[n+1] <- l230 - l234 - K*(2*n + 1)^2*pi^2/(4*l^2)
    gamma_0[n+1] <- l230*(1/(beta230[n+1] + l234) + (U48_0 - 1)*exp(-l234*t0)/(beta234[n+1]*beta230[n+1]))
    # series230_0[n+1] <- (-1)^n/(2*n + 1)*gamma[n+1]*exp(-K*(2*n + 1)^2*pi^2*t0/(4*l^2))*cos((2*n + 1)/2*pi*x/l)
    series230_0[n+1] <- (-1)/(2*n + 1)*gamma[n+1]*exp(-K*(2*n + 1)^2*pi^2*t0/(4*l^2))*cos((2*n + 1)/2*pi*x/l)
  }
  sum_series230_0 <- sum(series230_0)
  f[i] <- - A1_0*(1 + (U48_0 - 1)*cosh(x*(l234/K)^0.5)/(cosh(l*(l234/K)^0.5) - 4/pi*sum_series230_0))*exp(-l230*t)
  A3[i] <- f[i] + A1_0*(1 + (U48_0 - 1)*cosh(x*(l234/K)^0.5)/(cosh(l*(l234/K)^0.5) - 4/pi*sum_series230))
}
A2 <- DA2 + A1
U48calc <- A2/A1
Th0U8calc <- A3/A1
Th0U4calc <- A3/A2

# create vectors to show data across the bone, not just 1/2 the bone
x_vec <- c(rev(-x_vec/l), x_vec/l) 
U48calc <- c(rev(U48calc), U48calc)
Th0U8calc <- c(rev(Th0U8calc), Th0U8calc)
Th0U4calc <- c(rev(Th0U4calc), Th0U4calc)
U48meas <- c(rev(U48meas), U48meas)
Th0U8meas <- c(rev(Th0U8meas), Th0U8meas)

df <- as.data.frame(cbind(x_vec, U48calc, Th0U8calc, Th0U4calc, U48meas, Th0U8meas))

library(ggplot2)
ggplot() + geom_point(data = df, aes(x_vec, Th0U8calc), colour = 'red', size=3) + 
  geom_point(data = df, aes(x_vec, Th0U8meas), colour = 'blue', size=3) +
  xlab("Normalised distance from the center of the bone") +
  ylab("(230Th/238U)")
ggplot() + geom_point(data = df, aes(x_vec, U48calc), colour = 'red', size=3) + 
  geom_point(data = df, aes(x_vec, U48meas), colour = 'blue', size=3) +
  xlab("Normalised distance from the center of the bone") +
  ylab("(234U/238U)")

我期待以下结果:

new Promise(function(resolve, reject) { 
    // A mock async action using setTimeout
    setTimeout(function() { resolve(10); }, 3000);
})

.then(function(num) { 
    console.log('first then: ', num); return num * 2; })

.then(function(num) { 
    setTimeout(function() { 
        console.log('second then: ', num); return num * 2; }, 500);
    })

.then(function(num) { 
    console.log('last then: ', num);
});

// RESULT!
// From the console:
// first then:  10
// last then:  undefined
// second then:  20

1 个答案:

答案 0 :(得分:5)

第二个然后必须返回另一个承诺,如果你希望第三个​​然后在第二个然后的超时后触发。

此版本的代码将为您提供所需的结果:

new Promise(function (resolve) { 
    setTimeout(function() {
    	resolve(10);
    }, 3000);
})
.then(function (num) { 
    console.log('first then: ', num); return num * 2;
})
.then(function (num) { 
    return new Promise(function (resolve) {
    	setTimeout(function () { 
            console.log('second then: ', num);
            resolve(num * 2);
        }, 500);
    });
})
.then(function (num) { 
    console.log('last then: ', num);
});

你的代码没有按预期工作的原因是在第二次超时开始后立即调用第三个然后,调用setTimeout的结果是未定义

我看起来你期望从第二次超时的回调中返回的结果以某种方式作为第二个然后的结果传递,但这不是它的工作方式。